def create_rst_from_ipython_notebooks():
    curdir = os.getcwd()
    notebook_dir = os.path.join(pkg_path, '..', 'docs', 'quick_start', 'demo')
    pydocs_dir = os.path.join(pkg_path, '..', 'docs', 'html_docs', 'quick_start')

    assert os.path.exists(pydocs_dir), print_bad_path(quick_start_pydocs_dir)
    assert os.path.exists(notebook_dir), print_bad_path(notebook_dir)
    os.chdir(notebook_dir)
    for fname in os.listdir(notebook_dir):
        fnamei = os.path.basename(fname)
        base = os.path.splitext(fnamei)[0]
        fname2 = base + '.rst'

        if fnamei.startswith('.'):
            continue
        if not fnamei.endswith('.ipynb'):
            continue
        os.system('ipython nbconvert --to rst %s' % fname)
        if not os.path.exists(fname2):
            print('%s was not made...' % fname2)
            continue

        moved_fname2 = os.path.join(pydocs_dir, fname2)
        try:
            if os.path.exists(moved_fname2):
                os.remove(moved_fname2)
            os.rename(fname2, moved_fname2)
        except:
            pass
Example #2
0
def run_fem1(fem1, bdfModel, meshForm, xref, punch, sum_load, size, is_double, cid):
    """Reads/writes the BDF"""
    assert os.path.exists(bdfModel), print_bad_path(bdfModel)
    try:
        if '.pch' in bdfModel:
            fem1.read_bdf(bdfModel, xref=False, punch=True)
        else:
            fem1.read_bdf(bdfModel, xref=xref, punch=punch)
    except:
        print("failed reading %r" % bdfModel)
        raise
    #fem1.sumForces()

    if fem1._auto_reject:
        outModel = bdfModel + '.rej'
    else:
        outModel = bdfModel + '_out'
        if cid is not None and xref:
            fem1.resolve_grids(cid=cid)
        if meshForm == 'combined':
            fem1.write_bdf(outModel, interspersed=False, size=size, is_double=is_double)
        elif meshForm == 'separate':
            fem1.write_bdf(outModel, interspersed=False, size=size, is_double=is_double)
        else:
            msg = "meshForm=%r; allowedForms=['combined','separate']" % meshForm
            raise NotImplementedError(msg)
        #fem1.writeAsCTRIA3(outModel)

    fem1._get_maps()
    return outModel
Example #3
0
def run_fem1(fem1, bdfModel, meshForm, xref, punch, sum_load, size, is_double, cid):
    """
    Reads/writes the BDF

    Parameters
    ----------
    fem1 : BDF()
        The BDF object
    bdfModel : str
        The root path of the bdf filename
    meshForm : str {combined, separate}
        'combined' : interspersed=True
        'separate' : interspersed=False
    xref : bool
        The xref mode
    punch : bool
        punch flag
    sum_load : bool
        static load sum flag
    size : int, {8, 16}
        size flag
    is_double : bool
        double flag
    cid : int / None
        cid flag
    """
    assert os.path.exists(bdfModel), print_bad_path(bdfModel)
    try:
        if '.pch' in bdfModel:
            fem1.read_bdf(bdfModel, xref=False, punch=True)
        else:
            fem1.read_bdf(bdfModel, xref=False, punch=punch)
            if xref:
                #fem1.uncross_reference()
                fem1.cross_reference()
                #fem1.uncross_reference()
                #fem1.cross_reference()
    except:
        print("failed reading %r" % bdfModel)
        raise
    #fem1.sumForces()

    if fem1._auto_reject:
        out_model = bdfModel + '.rej'
    else:
        out_model = bdfModel + '_out'
        if cid is not None and xref:
            fem1.resolve_grids(cid=cid)

        if meshForm == 'combined':
            fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double)
        elif meshForm == 'separate':
            fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double)
        else:
            msg = "meshForm=%r; allowedForms=['combined','separate']" % meshForm
            raise NotImplementedError(msg)
        #fem1.writeAsCTRIA3(out_model)

    fem1._get_maps()
    return out_model
def run_bdfs(bdf_filenames, workpath='results', nastran_keywords=None,
             overwrite_op2_if_exists=False):
    assert os.path.exists(workpath), print_bad_path(workpath)

    curdir = os.getcwd()
    print('switching from %r to %r' % (curdir, workpath))
    os.chdir(workpath)

    #print(bdf_filenames)
    print('Start running patch jobs.')
    sys.stdout.flush()
    op2_filenames = []
    assert len(bdf_filenames) > 0, 'bdf_filenames=%s' % bdf_filenames
    for bdf_filename in bdf_filenames:
        basename = os.path.basename(bdf_filename)
        assert os.path.exists(bdf_filename)
        patch_id_str = basename.split('_')[1].split('.')[0]
        patch_id = int(patch_id_str)
        op2_filename = 'patch_%s.op2' % patch_id
        if not os.path.exists(op2_filename) or overwrite_op2_if_exists:
            #cmd = 'nastran %s scr=yes bat=no old=no' % (basename) # shell version

            call_args = ['nastran', bdf_filename, 'scr=yes', 'bat=no', 'old=no']
            for key, value in nastran_keywords.items():
                if key not in ['scr', 'bat', 'old']:
                    call_args.append('%s=%s' % (key, value))
            print(call_args)
            sys.stdout.flush()
            op2_filenames.append(os.path.join(workpath, op2_filename))

            subprocess.call(call_args)
    print('Done running patch jobs.')
    print('switching from %r to %r' % (workpath, curdir))
    os.chdir(curdir)
    return op2_filenames
Example #5
0
    def read_panair(self, infilename):
        assert os.path.exists(infilename), print_bad_path(infilename)
        self.infilename = infilename

        with open(self.infilename, 'r') as infile:
            self.lines = infile.readlines()

        lines = self.remove_comments(self.lines)
        (sections, section_names) = self.split_into_sections(lines)
        groups = self.group_sections(sections, section_names)
Example #6
0
    def read_panair(self, infileName):
        assert os.path.exists(infileName), print_bad_path(infileName)
        self.infileName = infileName

        infile = open(self.infileName, 'r')
        self.lines = infile.readlines()
        infile.close()

        lines = self.remove_comments(self.lines)
        (sections, sectionNames) = self.split_into_sections(lines)
        groups = self.group_sections(sections, sectionNames)
Example #7
0
    def __init__(self, infileName, log=None, debug=True):
        assert os.path.exists(infileName), print_bad_path(infileName)

        self.infileName = infileName
        self.nNetworks = 0
        self.patches = {}
        self.lines = []

        self.alphas = [0.]
        self.ncases = None
        self.betas = [0.]
        self.alphaC = 0.
        self.betaC = 0.

        self.sref = 1.
        self.bref = 1.
        self.cref = 1.
        self.dref = 1.

        self.xref = 0.
        self.yref = 0.
        self.zref = 0.

        self.isings = 0.0
        self.isingp = 0.0
        self.igeomp = 0.0
        self.icontp = 0.0
        self.ibconp = 0.0
        self.iedgep = 0.0
        self.ipraic = 0.0
        self.nexdgn = 0.0
        self.ioutpr = 0.0
        self.ifmcpr = 0.0
        self.icostp = 0.0

        self.isEnd = None

        self.peaSection = ''


        self.mach = 0.0
        self.dataCheck = 2
        self.titleSection = ''
        self.xyzSection = ''
        self.streamlineSection = ''
        self.flowSection = ''
        self.sectionalPropSection = ''
        self.gridSection = ''

        self.msg = ''

        self.log = get_logger(log, 'debug' if debug else 'info')
def create_rst_from_python_files():
    quick_start_pydocs_dir = os.path.join(pkg_path, '..', 'docs', 'quick_start', 'py_docs')
    pydocs_dir = os.path.join(pkg_path, '..', 'docs', 'html_docs', 'quck_start')
    if not os.path.exists(pydocs_dir):
        os.makedirs(pydocs_dir)

    assert os.path.exists(quick_start_pydocs_dir), print_bad_path(quick_start_pydocs_dir)
    for fname in os.listdir(quick_start_pydocs_dir):
        fname1 = os.path.join(quick_start_pydocs_dir, fname)
        fname2 = os.path.join(pydocs_dir, fname)
        print(fname1)
        print(fname2)
        shutil.copyfile(fname1, fname2)
    return
Example #9
0
def run_fem1(fem1, bdfModel, meshForm, xref, punch, cid):
    assert os.path.exists(bdfModel), print_bad_path(bdfModel)
    try:
        if '.pch' in bdfModel:
            fem1.read_bdf(bdfModel, xref=False, punch=True)
        else:
            fem1.read_bdf(bdfModel, xref=xref, punch=punch)
    except:
        print("failed reading |%s|" % (bdfModel))
        raise
    #fem1.sumForces()
    #fem1.sumMoments()
    outModel = bdfModel + '_out'
    if cid is not None and xref:
        fem1.resolveGrids(cid=cid)
    if meshForm == 'combined':
        fem1.write_bdf(outModel, interspersed=True)
    elif meshForm == 'separate':
        fem1.write_bdf(outModel, interspersed=False)
    else:
        msg = "meshForm=|%r| allowedForms=['combined','separate']" % (meshForm)
        raise NotImplementedError(msg)
    #fem1.writeAsCTRIA3(outModel)
    return (outModel)
Example #10
0
def run_fem1(fem1, bdf_model, mesh_form, xref, punch, sum_load, size, is_double, cid):
    assert os.path.exists(bdf_model), print_bad_path(bdf_model)
    try:
        if ".pch" in bdf_model:
            fem1.read_bdf(bdf_model, xref=False, punch=True)
        else:
            fem1.read_bdf(bdf_model, xref=xref, punch=punch)
    except:
        print("failed reading %r" % bdf_model)
        raise
    # fem1.sumForces()

    out_model = bdf_model + "v_out"
    if cid is not None and xref:
        fem1.resolveGrids(cid=cid)
    if mesh_form == "combined":
        fem1.write_bdf(out_model, interspersed=True, size=size, is_double=is_double)
    elif mesh_form == "separate":
        fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double)
    else:
        msg = "mesh_form=%r; allowedForms=['combined','separate']" % mesh_form
        raise NotImplementedError(msg)
    # fem1.writeAsCTRIA3(out_model)
    return out_model
Example #11
0
    def load_openfoam_geometry(self, openfoam_filename, dirname, mesh_3d, plot=True):
        #key = self.caseKeys[self.iCase]
        #case = self.resultCases[key]

        skip_reading = self.remove_old_openfoam_geometry(openfoam_filename)
        if skip_reading:
            return
        #print('self.modelType=%s' % self.modelType)
        print('mesh_3d = %s' % mesh_3d)
        if mesh_3d in ['hex', 'shell']:
            model = BlockMesh(log=self.log, debug=False) # log=self.log, debug=False
        elif mesh_3d == 'faces':
            model = BlockMesh(log=self.log, debug=False) # log=self.log, debug=False
            boundary = Boundary(log=self.log, debug=False)


        self.modelType = 'openfoam'
        #self.modelType = model.modelType
        print('openfoam_filename = %s' % openfoam_filename)

        is_face_mesh = False
        if mesh_3d == 'hex':
            is_3d_blockmesh = True
            is_surface_blockmesh = False
            (nodes, hexas, quads, names, patches) = model.read_openfoam(openfoam_filename)
        elif mesh_3d == 'shell':
            is_3d_blockmesh = False
            is_surface_blockmesh = True
            (nodes, hexas, quads, names, patches) = model.read_openfoam(openfoam_filename)
        elif mesh_3d == 'faces':
            is_3d_blockmesh = False
            is_surface_blockmesh = False
            is_face_mesh = True
            #(nodes, hexas, quads, names, patches) = model.read_openfoam(openfoam_filename)
        else:
            raise RuntimeError(mesh_3d)

        tris = []


        if mesh_3d == 'hex':
            self.nElements = len(hexas)
        elif mesh_3d == 'shell':
            self.nElements = len(quads)
        elif mesh_3d == 'faces':
            point_filename = os.path.join(dirname, 'points')
            face_filename = os.path.join(dirname, 'faces')
            boundary_filename = os.path.join(dirname, 'boundary')
            assert os.path.exists(face_filename), print_bad_path(face_filename)
            assert os.path.exists(point_filename), print_bad_path(point_filename)
            assert os.path.exists(boundary_filename), print_bad_path(boundary_filename)

            hexas = None
            patches = None
            nodes, quads, names = boundary.read_openfoam(
                point_filename, face_filename, boundary_filename)
            self.nElements = len(quads) + len(tris)
        else:
            raise RuntimeError(mesh_3d)

        self.nNodes = len(nodes)
        print("nNodes = %s" % self.nNodes)
        print("nElements = %s" % self.nElements)


        self.grid.Allocate(self.nElements, 1000)
        #self.gridResult.SetNumberOfComponents(self.nElements)
        self.grid2.Allocate(1, 1000)

        points = vtk.vtkPoints()
        points.SetNumberOfPoints(self.nNodes)
        #self.gridResult.Allocate(self.nNodes, 1000)
        #vectorReselt.SetNumberOfComponents(3)
        self.nidMap = {}
        #elem.SetNumberOfPoints(nNodes)
        if 0:
            fraction = 1. / self.nNodes  # so you can color the nodes by ID
            for nid, node in sorted(iteritems(nodes)):
                points.InsertPoint(nid - 1, *node)
                self.gridResult.InsertNextValue(nid * fraction)
                #print(str(element))

                #elem = vtk.vtkVertex()
                #elem.GetPointIds().SetId(0, i)
                #self.aQuadGrid.InsertNextCell(elem.GetCellType(), elem.GetPointIds())
                #vectorResult.InsertTuple3(0, 0.0, 0.0, 1.0)

        assert nodes is not None
        nnodes, three = nodes.shape

        nid = 0
        #print("nnodes=%s" % nnodes)
        mmax = amax(nodes, axis=0)
        mmin = amin(nodes, axis=0)
        dim_max = (mmax - mmin).max()
        self.update_axes_length(dim_max)

        f = open('points.bdf', 'wb')
        f.write('CEND\n')
        f.write('BEGIN BULK\n')

        unames = unique(names)
        for pid in unames:
            f.write('PSHELL,%i,1,0.1\n' % pid)
        f.write('MAT1,1,1.0e7,,0.3\n')

        if is_face_mesh:
            unodes = unique(quads)
            unodes.sort()
            # should stop plotting duplicate nodes
            for inode, node in enumerate(nodes):
                if inode in unodes:
                    f.write('GRID,%i,,%s,%s,%s\n' % (inode + 1, node[0], node[1], node[2], ))
                points.InsertPoint(inode, node)
        else:
            #print(nodes)
            for inode, node in enumerate(nodes):
                points.InsertPoint(inode, node)

        #elements -= 1
        normals = None
        if is_3d_blockmesh:
            nelements, three = hexas.shape
            for eid, element in enumerate(hexas):
                #print(element)
                elem = vtkHexahedron()
                elem.GetPointIds().SetId(0, element[0])
                elem.GetPointIds().SetId(1, element[1])
                elem.GetPointIds().SetId(2, element[2])
                elem.GetPointIds().SetId(3, element[3])
                elem.GetPointIds().SetId(4, element[4])
                elem.GetPointIds().SetId(5, element[5])
                elem.GetPointIds().SetId(6, element[6])
                elem.GetPointIds().SetId(7, element[7])
                self.grid.InsertNextCell(elem.GetCellType(),
                                         elem.GetPointIds())

                #elem = vtkTriangle()
                #node_ids = elements[eid, :]
                #elem.GetPointIds().SetId(0, node_ids[0])
                #elem.GetPointIds().SetId(1, node_ids[1])
                #elem.GetPointIds().SetId(2, node_ids[2])

                #elem.GetCellType() = 5  # vtkTriangle
                #self.grid.InsertNextCell(5, elem.GetPointIds())
        elif is_surface_blockmesh:
            nelements, four = quads.shape
            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())
        elif is_face_mesh:
            elems = quads
            nelements = quads.shape[0]
            nnames = len(names)
            normals = zeros((nelements, 3), dtype='float32')
            if nnames != nelements:
                msg = 'nnames=%s nelements=%s names.max=%s names.min=%s' % (
                    nnames, nelements, names.max(), names.min())
                raise RuntimeError(msg)
            for eid, element in enumerate(elems):
                #print('element = %s' % element)
                ineg = where(element == -1)[0]

                nnodes = 4
                if ineg:
                    nnodes = ineg.max()

                #pid = 1
                pid = names[eid]
                if nnodes == 3: # triangle!
                    f.write('CTRIA3,%i,%i,%i,%i,%i\n' % (
                        eid+1, pid, element[0]+1, element[1]+1, element[2]+1))
                    elem = vtkTriangle()
                    a = nodes[element[1], :] - nodes[element[0], :]
                    b = nodes[element[2], :] - nodes[element[0], :]
                    n = cross(a, b)
                    normals[eid, :] = n / norm(n)

                    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())
                elif nnodes == 4:
                    f.write('CQUAD4,%i,%i,%i,%i,%i,%i\n' % (
                        eid+1, pid, element[0]+1, element[1]+1, element[2]+1, element[3]+1))
                    a = nodes[element[2], :] - nodes[element[0], :]
                    b = nodes[element[3], :] - nodes[element[1], :]
                    n = cross(a, b)
                    normals[eid, :] = n / norm(n)

                    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())
                else:
                    raise RuntimeError('nnodes=%s' % nnodes)
        else:
            msg = 'is_surface_blockmesh=%s is_face_mesh=%s; pick one' % (
                is_surface_blockmesh, is_face_mesh)
            raise RuntimeError(msg)

        self.nElements = nelements
        self.grid.SetPoints(points)
        #self.grid2.SetPoints(points2)
        #self.grid.GetPointData().SetScalars(self.gridResult)
        #print(dir(self.grid) #.SetNumberOfComponents(0))
        #self.grid.GetCellData().SetNumberOfTuples(1);
        #self.grid.GetCellData().SetScalars(self.gridResult)
        self.grid.Modified()
        #self.grid2.Modified()
        self.grid.Update()
        #self.grid2.Update()
        print("updated grid")

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

        #assert loads is not None
        #if 'Mach' in loads:
            #avgMach = mean(loads['Mach'])
            #note = ':  avg(Mach)=%g' % avgMach
        #else:
            #note = ''
        #self.iSubcaseNameMap = {1: ['Cart3d%s' % note, '']}
        self.iSubcaseNameMap = {0: ['OpenFoam BlockMeshDict', '']}
        cases = {}
        ID = 1

        #print("nElements = ",nElements)
        f.write('ENDDATA\n')
        f.close()

        if mesh_3d == 'hex':
            form, cases = self._fill_openfoam_case(cases, ID, nodes, nelements, patches, names, normals, is_surface_blockmesh)
        elif mesh_3d == 'shell':
            form, cases = self._fill_openfoam_case(cases, ID, nodes, nelements, patches, names, normals, is_surface_blockmesh)
        elif mesh_3d == 'faces':
            if len(names) == nelements:
                is_surface_blockmesh = True
            form, cases = self._fill_openfoam_case(cases, ID, nodes, nelements, patches,
                                                   names, normals, is_surface_blockmesh)
        else:
            raise RuntimeError(mesh_3d)

        if plot:
            self._finish_results_io2(form, cases)
Example #12
0
versions = ['27']

for version in versions:
    v0 = version[0]
    egginfo_path = r'C:\Python%s\Scripts\egginfo.exe' % version
    python_path = r'C:\Python%s\python.exe' % version

    if v0 == '2':
        pkg_path = r'D:\work\pyNastran_py2x\pyNastran'
    elif v0 == '3':
        pkg_path = r'D:\work\pyNastran_py3x\pyNastran'
    else:
        raise NotImplementedError(version)

    test_dir = pkg_path + r'\pyNastran'
    egginfo = '%s pyNastran' % egginfo_path
    #print "egginfo =",egginfo
    test_path = r'%s\all_tests.py' % test_dir

    #print print_bad_path(egginfo_path)
    print(print_bad_path(test_path))

    tests = r'%s %s' % (python_path, test_path)
    print("tests = %r" % tests)

    code1 = os.system(egginfo)
    assert code1 == 0
    code2 = os.system(tests)
    assert code2 == 0

Example #13
0
def run_fem1(fem1, bdf_model, mesh_form, xref, punch, sum_load, size, is_double, cid,
             encoding=None):
    """
    Reads/writes the BDF

    Parameters
    ----------
    fem1 : BDF()
        The BDF object
    bdf_model : str
        The root path of the bdf filename
    mesh_form : str {combined, separate}
        'combined' : interspersed=True
        'separate' : interspersed=False
    xref : bool
        The xref mode
    punch : bool
        punch flag
    sum_load : bool
        static load sum flag
    size : int, {8, 16}
        size flag
    is_double : bool
        double flag
    cid : int / None
        cid flag
    """
    assert os.path.exists(bdf_model), print_bad_path(bdf_model)
    try:
        if '.pch' in bdf_model:
            fem1.read_bdf(bdf_model, xref=False, punch=True, encoding=encoding)
        else:
            fem1.read_bdf(bdf_model, xref=False, punch=punch, encoding=encoding)
            #fem1.geom_check(geom_check=True, xref=False)
            fem1.write_skin_solid_faces('skin_file.bdf', size=16, is_double=False)
            if xref:
                #fem1.uncross_reference()
                fem1.cross_reference()
                fem1._xref = True
                spike_fem = read_bdf(fem1.bdf_filename, encoding=encoding)

                remake = False
                if remake:
                    log = fem1.log
                    fem1.save('model.obj')
                    fem1.save('model.obj', unxref=False)
                    fem1.write_bdf('spike_out.bdf')
                    fem1.get_bdf_stats()

                    fem1 = BDF()
                    fem1.load('model.obj')
                    fem1.write_bdf('spike_in.bdf')
                    fem1.log = log
                    fem1.get_bdf_stats()

                    fem1.cross_reference()
                    #fem1.get_bdf_stats()
                    fem1._xref = True

                #fem1.geom_check(geom_check=True, xref=True)
                #fem1.uncross_reference()
                #fem1.cross_reference()
    except:
        print("failed reading %r" % bdf_model)
        raise
    #fem1.sumForces()

    if fem1._auto_reject:
        out_model = bdf_model + '.rej'
    else:
        out_model = bdf_model + '_out'
        if cid is not None and xref:
            fem1.resolve_grids(cid=cid)

        if mesh_form == 'combined':
            fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double)
        elif mesh_form == 'separate':
            fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double)
        else:
            msg = "mesh_form=%r; allowedForms=['combined','separate']" % mesh_form
            raise NotImplementedError(msg)
        #fem1.writeAsCTRIA3(out_model)

    fem1._get_maps()
    return out_model, fem1
Example #14
0
    def __init__(self, f06FileName, debug=False, log=None):
        """
        Initializes the F06 object

        :f06FileName: the file to be parsed
        :makeGeom:    reads the BDF tables (default=False)
        :debug:       prints data about how the F06 was parsed (default=False)
        :log:         a logging object to write debug messages to
        
        .. seealso:: import logging
        """
        self.f06FileName = f06FileName
        if not os.path.exists(self.f06FileName):
            msg = 'cant find F06FileName=|%s|\n%s' % (
                self.f06FileName, print_bad_path(self.f06FileName))
            raise RuntimeError(msg)
        self.infile = open(self.f06FileName, 'r')
        self.__initAlt__(debug, log)

        self.lineMarkerMap = {
            'R E A L   E I G E N V E C T O R   N O': self.getRealEigenvectors,
        }
        self.markerMap = {
            #'N A S T R A N    F I L E    A N D    S Y S T E M    P A R A M E T E R    E C H O':self.fileSystem,
            #'N A S T R A N    E X E C U T I V E    C O N T R O L    E C H O':self.executiveControl,
            #'C A S E    C O N T R O L    E C H O ':self.caseControl,
            #'M O D E L   S U M M A R Y':self.summary,

            #'E L E M E N T   G E O M E T R Y   T E S T   R E S U L T S   S U M M A R Y'
            'O U T P U T   F R O M   G R I D   P O I N T   W E I G H T   G E N E R A T O R': self.getGridWeight,
            #'OLOAD    RESULTANT':self.oload,
            #'MAXIMUM  SPCFORCES':self.getMaxSpcForces,
            #'MAXIMUM  DISPLACEMENTS': self.getMaxDisplacements,
            #'MAXIMUM  APPLIED LOADS': self.getMaxAppliedLoads,
            #'G R I D   P O I N T   S I N G U L A R I T Y   T A B L E': self.gridPointSingularities,


            #------------------------
            #    N O N - D I M E N S I O N A L   S T A B I L I T Y   A N D   C O N T R O L   D E R I V A T I V E   C O E F F I C I E N T S
            #          N O N - D I M E N S I O N A L    H I N G E    M O M E N T    D E R I V A T I V E   C O E F F I C I E N T S
            #                               A E R O S T A T I C   D A T A   R E C O V E R Y   O U T P U T   T A B L E S
            #                              S T R U C T U R A L   M O N I T O R   P O I N T   I N T E G R A T E D   L O A D S
            #------------------------
            #                                    R O T O R   D Y N A M I C S   S U M M A R Y
            #                              R O T O R   D Y N A M I C S   M A S S   S U M M A R Y
            #                           E I G E N V A L U E  A N A L Y S I S   S U M M A R Y   (COMPLEX LANCZOS METHOD)
            #------------------------

            'R E A L   E I G E N V A L U E S': self.getRealEigenvalues,
            #'C O M P L E X   E I G E N V A L U E   S U M M A R Y':self.getComplexEigenvalues,
            'E L E M E N T   S T R A I N   E N E R G I E S': self.getElementStrainEnergies,
            'D I S P L A C E M E N T   V E C T O R': self.getDisplacement,
            'C O M P L E X   D I S P L A C E M E N T   V E C T O R': self.getComplexDisplacement,
            'F O R C E S   O F   S I N G L E - P O I N T   C O N S T R A I N T': self.getSpcForces,
            'F O R C E S   O F   M U L T I P O I N T   C O N S T R A I N T': self.getMpcForces,
            #'G R I D   P O I N T   F O R C E   B A L A N C E':self.getGridPointForces,

            'S T R E S S E S   I N   B A R   E L E M E N T S          ( C B A R )': self.getBarStress,
            'S T R E S S E S   I N   R O D   E L E M E N T S      ( C R O D )': self.getRodStress,

            'S T R E S S E S   I N   T R I A N G U L A R   E L E M E N T S   ( T R I A 3 )': self.getTriStress,
            'S T R E S S E S   I N   Q U A D R I L A T E R A L   E L E M E N T S   ( Q U A D 4 )': self.getQuadStress,
            'S T R E S S E S   I N   Q U A D R I L A T E R A L   E L E M E N T S   ( Q U A D 4 )        OPTION = BILIN': self.getQuadStressBilinear,
            'S T R E S S E S   I N   L A Y E R E D   C O M P O S I T E   E L E M E N T S   ( Q U A D 4 )': self.getQuadCompositeStress,

            'S T R E S S E S   I N    T E T R A H E D R O N   S O L I D   E L E M E N T S   ( C T E T R A )': self.getSolidStressTetra,
            'S T R E S S E S   I N   H E X A H E D R O N   S O L I D   E L E M E N T S   ( H E X A )': self.getSolidStressHexa,
            'S T R E S S E S   I N   P E N T A H E D R O N   S O L I D   E L E M E N T S   ( P E N T A )': self.getSolidStressPenta,

            'S T R A I N S    I N   B A R   E L E M E N T S          ( C B A R )': self.getBarStrain,
            'S T R A I N S   I N   R O D   E L E M E N T S      ( C R O D )': self.getRodStrain,

            'S T R A I N S   I N   Q U A D R I L A T E R A L   E L E M E N T S   ( Q U A D 4 )': self.getQuadStrains,
            'S T R A I N S   I N   T R I A N G U L A R   E L E M E N T S   ( T R I A 3 )': self.getTriStrain,

            'S T R A I N S   I N    T E T R A H E D R O N   S O L I D   E L E M E N T S   ( C T E T R A )': self.getSolidStrainTetra,
            'S T R A I N S   I N   H E X A H E D R O N   S O L I D   E L E M E N T S   ( H E X A )': self.getSolidStrainHexa,
            'S T R A I N S   I N   P E N T A H E D R O N   S O L I D   E L E M E N T S   ( P E N T A )': self.getSolidStrainPenta,

            'T E M P E R A T U R E   V E C T O R': self.getTemperatureVector,
            'F I N I T E   E L E M E N T   T E M P E R A T U R E   G R A D I E N T S   A N D   F L U X E S': self.getTempGradientsFluxes,

            #'* * * END OF JOB * * *': self.end(),
        }
        self.markers = list(self.markerMap.keys())
Example #15
0
    def read_f06(self, f06_filename=None):
        """
        Reads the F06 file

        :self: the object pointer

        :f06FileName: the file to be parsed (None -> GUI)
        """
        if f06_filename is None:
            from pyNastran.utils.gui_io import load_file_dialog
            wildcard_wx = "Nastran F06 (*.f06)|*.f06|" \
                "All files (*.*)|*.*"
            wildcard_qt = "Nastran F06 (*.f06);;All files (*)"
            title = 'Please select a F06 to load'
            f06_filename = load_file_dialog(title, wildcard_wx, wildcard_qt)
            assert f06_filename is not None, f06_filename
        else:
            if not os.path.exists(f06_filename):
                msg = 'cant find f06_filename=%r\n%s' \
                    % (f06_filename, print_bad_path(f06_filename))
                raise RuntimeError(msg)

        if is_binary(f06_filename):
            raise IOError('f06_filename=%r is not a binary F06.' % f06_filename)
        if os.path.getsize(f06_filename) == 0:
            raise IOError('f06_filename=%r is empty.' % f06_filename)

        self.log.debug('f06_filename = %r' % f06_filename)
        self.f06_filename = f06_filename


        blank = 0
        self.infile = open(self.f06_filename, 'r')
        while 1:
            #if self.i % 1000 == 0:
                #print("i=%i" % (self.i))
            line = self.infile.readline()
            marker = line[1:].strip()

            if 'FATAL' in marker and 'IF THE FLAG IS FATAL' not in marker:
                msg = '\n' + marker
                fatal_count = 0
                while 1:
                    line = self.infile.readline().rstrip()
                    #print("blank = %s" % blank)
                    fatal_count += 1
                    if fatal_count == 20 or '* * * END OF JOB * * *' in line:
                        break
                    #else:
                        #blank = 0
                    msg += line + '\n'
                raise FatalError(msg.rstrip())

            if(marker != '' and 'SUBCASE' not in marker and 'PAGE' not in marker and 'FORTRAN' not in marker
               and 'USER INFORMATION MESSAGE' not in marker and 'TOTAL DATA WRITTEN FOR DATA BLOCK' not in marker
               and marker not in self.markers and marker != self._subtitle):
                #print("marker = %r" % marker)
                pass
                #print('Title  = %r' % self.subtitle)

            if marker in self.markers:
                blank = 0
                #print("\n1*marker = %r" % marker)
                self._marker_map[marker]()
                if(self._stop_after_reading_mass and
                   marker in 'O U T P U T   F R O M   G R I D   P O I N T   W E I G H T   G E N E R A T O R'):
                    break
                self.stored_lines = []
            elif 'R E A L   E I G E N V E C T O R   N O' in marker:
                blank = 0
                #print("\n2*marker = %r" % marker)
                self._line_marker_map['R E A L   E I G E N V E C T O R   N O'](marker)
                #print('done with real eigenvector')
                self.stored_lines = []
            elif 'C O M P L E X   E I G E N V E C T O R   NO' in marker:
                blank = 0
                #print("\n2*marker = %r" % marker)
                self._line_marker_map['C O M P L E X   E I G E N V E C T O R   NO'](marker)
                self.stored_lines = []

            elif 'News file -' in marker:
                blank = 0
                self._line_marker_map['News file -']()
                self.stored_lines = []
            elif marker == '':
                blank += 1
                if blank == 20:
                    break
            elif self._is_marker(marker):  # marker with space in it (e.g. Model Summary)
                print("***marker = %r" % marker)

            else:
                blank = 0

            self.stored_lines.append(line)
            self.i += 1
        #print("i=%i" % self.i)
        self.infile.close()
        self._process_f06()
        if hasattr(self, '_ieigenvalue'):
            del self._ieigenvalue
        self.build_vectorization()
Example #16
0
    def read_fgrid(self, fgrid_filename, dimension_flag=3):
        assert os.path.exists(fgrid_filename), print_bad_path(fgrid_filename)
        with open(fgrid_filename, 'r') as fgrid:
            nnodes, ntris, ntets = fgrid.readline().split()
            nnodes = int(nnodes)
            ntris = int(ntris)
            ntets = int(ntets)

            nodesi = np.zeros((nnodes * 3), dtype='float32')
            tris = np.zeros((ntris, 3), dtype='int32')
            assert nnodes > 0, nnodes
            i0 = 0
            # I think this goes xxx, yyy, zzz
            # instead of x, y, z
            #            x, y, z
            for i in range(nnodes):
                #nodes[i, :] = fgrid.readline().split()
                #nodes[i0:i1] = fgrid.readline().split()
                sline = fgrid.readline().split()
                #x[i] = sline[0]
                #y[i] = sline[1]
                #z[i] = sline[2]
                nodesi[i0] = sline[0]
                nodesi[i0 + 1] = sline[1]
                nodesi[i0 + 2] = sline[2]
                i0 += 3

            #nodes = vstack([x, y, z]).T
            #nodes = hstack([x, y, z]).reshape((3, nnodes)).T
            #nodes = hstack([x, y, z]).reshape((3, nnodes)).T
            #nodes = nodesi.reshape((nnodes, 3))
            nodes = nodesi.reshape((3, nnodes)).T
            #print('nodes.shape = %s' % str(nodes.shape))
            ntri_lines = ntris // 2
            j = 0
            for i in range(ntri_lines):
                sline = fgrid.readline().split()
                tris[j, :] = sline[:3]
                tris[j + 1, :] = sline[3:]
                j += 2

            #k = 0
            if ntris % 2: # if there's a leftover line
                tris[j] = sline[:3]
                #bcs[:3] = sline[3:]
                #k = 3

            nquestion = ntris // 3 // 2
            for i in range(nquestion):
                sline = fgrid.readline().split()

            #sline = fgrid.readline().split()
            # nnodes=16391
            # ntris=4512
            # ntets = 90892
            # 60595 lines * 6/4 = 90892.5
            #752, 753 = 4512/3/2
            #assert sline == ['15770','15767','16242','15772','15765','15762'], sline

            #ntet_lines = ntets * 6 // 44

            tets = np.zeros(ntets * 4, dtype='int32')
            tets[:] = fgrid.read().split()
            tets = tets.reshape((ntets, 4))

        self.nodes = nodes
        self.tris = tris
        self.tets = tets
Example #17
0
versions = ['27']

for version in versions:
    v0 = version[0]
    egginfo_path = r'C:\Python%s\Scripts\egginfo.exe' % version
    python_path = r'C:\Python%s\python.exe' % version
    
    if v0 == '2':
        pkg_path = r'D:\work\pyNastran_py2x\pyNastran'
    elif v0 == '3':
        pkg_path = r'D:\work\pyNastran_py3x\pyNastran'
    else:
        raise NotImplementedError(version)

    test_dir = pkg_path + r'\pyNastran'
    egginfo = '%s pyNastran' % egginfo_path
    #print "egginfo =",egginfo
    test_path = r'%s\all_tests.py' % test_dir

    #print print_bad_path(egginfo_path)
    print print_bad_path(test_path)

    tests = r'%s %s' % (python_path, test_path)
    print "tests = %r" % tests

    code1 = os.system(egginfo)
    assert code1 == 0
    code2 = os.system(tests)
    assert code2 == 0

Example #18
0
#op4.read_op4?
help(op4.read_op4)

# <codecell>

# read the op4, will pop open a dialog box
#matrices = op4.read_op4()

#print matrices.keys()
#key = 'CMPLX'
#print matrices[key]

# <codecell>

op4_filename = r'C:\Users\Steve\Desktop\ISat_Launch_Sm_4pt.op4'
assert os.path.exists(op4_filename), print_bad_path(op4_filename)

#specify the file
matrices = op4.read_op4(op4_filename)

# <codecell>

# more ways to read a matrix

# only 1 matrix
matrices = op4.read_op4(op4_filename, matrix_names='FLAMA')

# 1 or more matrices
matrices = op4.read_op4(op4_filename, matrix_names=['FLAMA','UGEXT'])

# <codecell>
Example #19
0
    def read_openfoam(self, point_filename, face_filename, boundary_filename):
        assert os.path.exists(face_filename), print_bad_path(face_filename)
        assert os.path.exists(point_filename), print_bad_path(point_filename)
        assert os.path.exists(boundary_filename), print_bad_path(boundary_filename)

        print('face_filename = %r' % face_filename)
        print('point_filename = %r' % point_filename)
        print('boundary_filename = %r' % boundary_filename)

        assert 'faces' in face_filename, face_filename
        assert 'points' in point_filename, point_filename
        assert 'boundary' in boundary_filename, boundary_filename

        print('starting Boundary')
        p = PointFile(log=None, debug=True)
        #from PyFoam.RunDictionary.ParsedBlockMeshDict import ParsedBlockMeshDict
        #print(dir(f))

        f = FaceFile(log=None, debug=True)

        b = BoundaryFile(log=None, debug=False)
        boundaries = b.read_boundary_file(boundary_filename)

        if 0:
            b = FoamFile(boundary_filename, log=p.log)

            print('getting lines')
            blines = b.read_foam_file()
            print('converting')
            bd = convert_to_dict(b, blines, debug=True)
            del blines


        print('getting npoints')
        #print write_dict(d)

        #-------------------------------------------
        # count number of faces by looking at the boundary info
        # so we can allocate faces2
        nfaces2 = 0
        ifaces_to_read = []
        #f_boundary_faces = open('boundary_faces.py', 'wb')
        for name, boundary in iteritems(boundaries):
            # type            patch;  # 0
            # nFaces          nFaces; # 1
            # startFace       777700; # 2
            print('boundary[%s] = %s' % (name, boundary))
            nfacesi = boundary[1]
            startface = int(boundary[2])
            nfaces2 += nfacesi
            new_faces = list(arange(nfacesi, dtype='int32') + startface)
            #f_boundary_faces.write('boundary_faces[%s, %s] = %s\n' % (name, len(new_faces), new_faces))
            ifaces_to_read += new_faces

        print('nfaces2 = ', nfaces2)
        ifaces_to_read = ravel(ifaces_to_read)
        assert len(ifaces_to_read) == nfaces2, 'len(ifaces_to_read)=%s nfaces2=%s' % (ifaces_to_read.shape, nfaces2)
        print(ifaces_to_read)

        faces = f.read_face_file(face_filename, ifaces_to_read=ifaces_to_read)
        #faces = f.read_face_file(face_filename, ifaces_to_read=None)
        del ifaces_to_read

        if 0:
            # doesn't work for some reason...
            # we want to only plot a subset of faces to reduce the data set
            # that works, but we also need to decrease the number of nodes (they take wayyy too long)

            # so we take our faces, get the unique nodes
            # sort them so they're consistent with the order in the file using the same block of code
            # that works in the face reader, but it still fails for some reason...

            # after this step, we renumber the faces with the adjusted node ids
            ipoints_to_read = unique(faces.ravel())
            print('nnodes = %s' % len(ipoints_to_read))
            ipoints_to_read.sort()
            print('ipoints_to_read = %s' % ipoints_to_read)
        else:
            ipoints_to_read = None
        nodes = p.read_point_file(point_filename, ipoints_to_read=ipoints_to_read)

        if ipoints_to_read is not None:
            nid_to_ipoint = {}
            for i, nid in enumerate(ipoints_to_read):
                nid_to_ipoint[nid] = i

            print(faces, faces.max())
            for i, face in enumerate(faces):
                #print('face      = %s' % face)
                faces[i, 0] = nid_to_ipoint[faces[i, 0]]
                faces[i, 1] = nid_to_ipoint[faces[i, 1]]
                faces[i, 2] = nid_to_ipoint[faces[i, 2]]
                #print('faces[%i] = %s' % (i, faces[i, :]))
            print(faces, faces.max())
            print('done...')
            del ipoints_to_read
            del nid_to_ipoint
        #-------------------------------------------
        # keep only the required faces
        iface = 0
        #faces2 = zeros((nfaces2, 4), dtype='int32')
        names = zeros(nfaces2, dtype='int32')
        iname = 1
        snames = [None] * (len(boundaries) + 1)
        self.log.info('')
        for name, boundary in iteritems(boundaries):
            self.log.info('iname=%s name=%s boundary=%s' % (iname, name, boundary))
            # type            patch;
            # nFaces          nFaces;
            # startFace       777700;
            try:
                Type = boundary[0]
                nfacesi = int(boundary[1])
                startface = int(boundary[2])
            except:
                print(boundary.keys())
                raise
            #faces2[iface:iface+nfacesi] = faces[startface:startface + nfacesi]
            names[iface:iface+nfacesi] = iname
            snames[iname] = name
            iface += nfacesi
            iname += 1
        #del faces
        quads = faces


        if 0:
            f_boundary_faces.write('\n\n---Faces----\n')
            for iface, face in enumerate(faces):
                pid = names[iface]
                name = snames[pid]
                f_boundary_faces.write('%i (%i %i %i %i) pid=%s name=%s\n' % (iface, face[0], face[1], face[2], face[3], pid, name))

            f_boundary_faces.write('\n\n---First Faces----\n')
            pid_save = set([])
            for iface, face in enumerate(faces):
                pid = names[iface]
                if pid not in pid_save:
                    name = snames[pid]
                    f_boundary_faces.write('%i (%i %i %i %i) pid=%s name=%s\n' % (iface, face[0], face[1], face[2], face[3], pid, name))
                    pid_save.add(pid)

        # only save the unique nodes
        # ...
        #unodes = unique(quads.ravel())
        #unodes.sort()
        #nodes = nodes[unodes, :]

        # renumber the nodes on the faces
        # ...
        self.log.debug('names=%s; max=%s min=%s' % (names, names.max(), names.min()))

        print('done with Boundary')
        #self.nodes = nodes
        return nodes, quads, names
Example #20
0
def run_docopt():
    msg  = "Usage:\n"
    msg += "  pyNastranGUI [-f FORMAT] INPUT [-o OUTPUT]\n"
    msg += '               [-s SHOT] [-m MAGNIFY]\n'  #  [-r XYZ]
    msg += '               [-g GSCRIPT] [-p PSCRIPT]\n'
    msg += '               [-u POINTS_FNAME...] [--user_geom GEOM_FNAME...]\n'
    msg += '               [-q] [--groups] [--noupdate]\n'
    msg += "  pyNastranGUI [-f FORMAT] INPUT OUTPUT [-o OUTPUT]\n"
    msg += '               [-s SHOT] [-m MAGNIFY]\n'  #  [-r XYZ]
    msg += '               [-g GSCRIPT] [-p PSCRIPT]\n'
    msg += '               [-u POINTS_FNAME...] [--user_geom GEOM_FNAME...]\n'
    msg += '               [-q] [--groups] [--noupdate]\n'
    msg += "  pyNastranGUI [-f FORMAT] [-i INPUT] [-o OUTPUT...]\n"
    msg += '               [-s SHOT] [-m MAGNIFY]\n'  #  [-r XYZ]
    msg += '               [-g GSCRIPT] [-p PSCRIPT]\n'
    msg += '               [-u POINTS_FNAME...] [--user_geom GEOM_FNAME...]\n'
    msg += '               [-q] [--groups] [--noupdate]\n'
    msg += '  pyNastranGUI -h | --help\n'
    msg += '  pyNastranGUI -v | --version\n'
    msg += "\n"
    msg += "Primary Options:\n"
    msg += "  -f FORMAT, --format FORMAT  format type (avus, cart3d, lawgs, nastran, panair, plot3d,\n"
    msg += "                                           stl, surf, tetgen, usm3d, ugrid)\n"
    msg += "  -i INPUT, --input INPUT     path to input file\n"
    msg += "  -o OUTPUT, --output OUTPUT  path to output file\n"
    #msg += "  -r XYZ, --rotation XYZ      [x, y, z, -x, -y, -z] default is ???\n"
    msg += '\n'

    msg += "Secondary Options:\n"
    msg += "  -g GSCRIPT, --geomscript        path to geometry script file (runs before load geometry)\n"
    msg += "  -p PSCRIPT, --postscript        path to post script file (runs after load geometry)\n"
    msg += "  -s SHOT, --shots SHOT           path to screenshot (only 1 for now)\n"
    msg += "  -m MAGNIFY, --magnify           how much should the resolution on a picture be magnified [default: 5]\n"
    msg += "  --groups                        enables groups\n"
    msg += "  --noupdate                      disables the update check\n"
    msg += "  --user_geom GEOM_FNAME          add user specified points to an alternate grid (repeatable)\n"
    msg += "  -u POINTS_FNAME, --user_points  add user specified points to an alternate grid (repeatable)\n"
    msg += '\n'

    msg += "Info:\n"
    msg += "  -q, --quiet    prints debug messages (default=True)\n"
    msg += "  -h, --help     show this help message and exit\n"
    msg += "  -v, --version  show program's version number and exit\n"


    ver = str(pyNastran.__version__)
    data = docopt(msg, version=ver)
    #print(data)

    input_format = data['--format']

    input_filenames = []
    if data['INPUT']:
        input_filenames += [data['INPUT']]
    if data['--input']:
        input_filenames += [data['--input']]
    for input_filename in input_filenames:
        assert os.path.exists(input_filename), print_bad_path(input_filename)

    output_filenames = []
    if data['OUTPUT']:
        output_filenames += [data['OUTPUT']]
    if data['--output']:
        output_filenames += data['--output']
    for output_filename in output_filenames:
        assert os.path.exists(output_filename), print_bad_path(output_filename)
    debug = not(data['--quiet'])

    # used to include None...
    allowed_formats = [
        'nastran', 'stl', 'cart3d', 'tecplot', 'ugrid', 'panair',
        #'plot3d',
        'surf', 'lawgs', 'degen_geom', 'shabp', 'avus', 'fast', 'abaqus', 'usm3d', 'bedge',
    ]

    if input_filenames and not input_format:
        input_format = determine_format(input_filenames[0], allowed_formats)

    # None is for custom geometry
    allowed_formats.append(None)
    assert input_format in allowed_formats, 'format=%r is not supported' % input_format

    shots = []
    if '--shots' in data:
        shots = data['--shots']

    geom_script = data['--geomscript']
    if geom_script:
        assert os.path.exists(geom_script), print_bad_path(geom_script)

    post_script = data['--postscript']
    if post_script:
        assert os.path.exists(post_script), print_bad_path(post_script)

    magnify = 1
    if '--magnify' in data and data['--magnify'] is not None:
        magnify = int(data['--magnify'])

    rotation = None
    if '--rotation' in data:
        rotation = data['--rotation']

    user_points = data['--user_points']
    user_geom = data['--user_geom']

    for key, value in sorted(iteritems(data)):
        print(key, value)
    #print("shots", shots)
    if shots:
        #shots = shots[1]
        #print("shots2 = %r" % shots, type(shots))
        shots = shots.split(';')[0]

    is_groups = data['--groups']
    no_update = data['--noupdate']
    #assert data['--console'] == False, data['--console']
    return (input_format, input_filenames, output_filenames, shots,
            magnify, rotation, geom_script, post_script, debug, user_points, user_geom,
            is_groups, no_update)
Example #21
0
    def read_bedge(self, bedge_filename, beta_reverse=179.7):
        """reads a *.bedge file"""
        base, ext = os.path.splitext(bedge_filename)
        assert ext == '.bedge', print_bad_path(bedge_filename)

        with open(bedge_filename, 'r') as bedge_file:
            data = bedge_file.read().split()

        i = 0
        ncurves = int(data[i])
        self.log.debug('ncurves = %s' % ncurves)
        i += 1

        inode_curve_min = [None] * ncurves
        inode_curve_max = [None] * ncurves

        nsubcurves_per_curve = [None] * ncurves
        for icurve in range(ncurves):
            nsubcurvesi = int(data[i])
            nsubcurves_per_curve[icurve] = nsubcurvesi
            i += 1
        del icurve

        self.log.debug('nsubcurves_per_curve = %s' % nsubcurves_per_curve)
        nsubcurves = sum(nsubcurves_per_curve)
        self.log.debug('nsubcurves = %s' % nsubcurves)

        self.log.debug('data[%i] = %s; nnodes[0]\n' % (i, data[i]))

        nnodes_pack = [None] * nsubcurves
        for isubcurve in range(nsubcurves):
            nnodesi = int(data[i])
            nnodes_pack[isubcurve] = nnodesi
            i += 1
        del isubcurve

        nnodes = sum(nnodes_pack)
        self.log.debug('nnodes_pack = %s' % nnodes_pack)
        self.log.debug('nnodes = %s' % nnodes)


        inode = 0
        isubcurve = 0
        isubcurve_to_curve_map = [None] * nsubcurves
        for icurve in range(ncurves):
            nsubcurvesi = nsubcurves_per_curve[icurve]
            inode_curve_min[icurve] = inode
            #delta_node_id = 0
            for isubcurvei in range(nsubcurvesi):
                nnodesi = nnodes_pack[isubcurve]
                #max_node_id += nnodesi
                inode += nnodesi
                isubcurve_to_curve_map[isubcurve] = icurve
                isubcurve += 1
            inode_curve_max[icurve] = inode # max_node_id
        inode_curve_min.append(nnodes)
        inode_curve_max.append(nnodes)
        self.log.debug("isubcurve_to_curve_map = %s" % isubcurve_to_curve_map)
        del icurve, isubcurvei

        # grid BC
        self.log.debug('data[%i]=%s; grid_bc[0]\n' % (i, data[i]))
        grid_bc = [None] * nsubcurves
        for isubcurve in range(nsubcurves):
            grid_bci = int(data[i])
            grid_bc[isubcurve] = grid_bci
            i += 1
        del isubcurve
        self.log.debug('grid_bc = %s' % grid_bc)
        #if grid_bc[0] in [2]:
            #raise RuntimeError('fname=%s' % bedge_filename)
        self.log.debug('data[%i] = %s; nid.x\n' % (i, data[i]))
        #=============================================================

        nodes = zeros((nnodes, 3), dtype='float64')

        # just for testing
        #assert data[i] == '4.87406', 'val=%s fname=%s' % (data[i], bedge_filename)
        istart = i
        for inode in range(nnodes):
            try:
                node = [data[i], data[i+1], 0.]
            except IndexError:
                nactual = len(data)
                nexpected = istart + nnodes * 2
                msg = ('error with data; inode=%s; len(data)=%s '
                       'len(data_expected)=%s; nmissing=%s' % (
                           inode, nactual, nexpected, nexpected - nactual))
                raise IndexError(msg)
            #print('node[%i] = %s' % (inode, node))
            nodes[inode, :] = node
            #assert nodes[inode, 0] == 21., node
            i += 2
        self.log.debug('node[0] = %s' % nodes[0, :])
        self.log.debug('node[%i] = %s' % (inode, node))
        #self.log.debug('nodes = %s' % nodes[:, :2])
        del inode


        initial_normal_spacing = zeros(nnodes, dtype='float64')
        if len(data) != i:
            initial_normal_spacingi = data[i]
            if '*' in initial_normal_spacingi:
                self.log.debug('initial_normal_spacingi = %s' % initial_normal_spacingi)
                nnodesi, initial_normal_spacingi = initial_normal_spacingi.split('*')
                nnodesi = int(nnodesi)
                initial_normal_spacing[:nnodesi] = initial_normal_spacingi
                i += 1
            else:
                for inode in range(nnodes):
                    initial_normal_spacingi = data[i]
                    initial_normal_spacing[inode] = initial_normal_spacingi
                    i += 1

        assert len(data) == i, 'len(data)=%s i=%s' % (len(data), i)

        #==================================================
        # build the outputs

        ielement0 = 0
        nelements = nnodes
        curves = zeros(nelements, dtype='int32')
        subcurves = zeros(nelements, dtype='int32')
        grid_bcs = zeros(nelements, dtype='int32')
        self.log.debug('***ncurves = %s' % ncurves)

        for isubcurve in range(nsubcurves):
            nnodesi = nnodes_pack[isubcurve]
            icurve = isubcurve_to_curve_map[isubcurve]
            bc = grid_bc[isubcurve]
            self.log.debug('isubcurve=%s icurve=%s grid_bc=%s' % (isubcurve, icurve, bc))

            curves[ielement0:ielement0+nnodesi] = icurve
            subcurves[ielement0:ielement0+nnodesi] = isubcurve
            grid_bcs[ielement0:ielement0+nnodesi] = bc
            ielement0 += nnodesi
        del icurve

        inode0 = 0
        bars_list = []
        turn_angle_list = []
        for isubcurve in range(nsubcurves):
            nnodesi = nnodes_pack[isubcurve]
            nbars = nnodesi
            inode = inode0 + nnodesi
            inodes = array([inode0 + inodei for inodei in range(0, nnodesi)])

            bars = zeros((nbars, 2), dtype='int32')
            inode_last = inodes[-1]

            icurve = isubcurve_to_curve_map[isubcurve]
            #print('isubcurve=%s icurve=%s inode_last=%s nnodes=%s' % (
                #isubcurve, icurve, inode_last, nnodes))
            #print('inode_curve_max = %s' % (inode_curve_max))
            #print('inode_curve_min = %s' % (inode_curve_min))
            if inode_last + 1 == nnodes:
                inode_last = inode_curve_min[icurve]
                #print('A')
                #inode_last = 0
            elif inode_last + 1 == inode_curve_max[icurve]:
                inode_last = inode_curve_min[icurve]  # inodes[0] ???
                #print('B')
            #elif inode_last == inode_curve_min[icurve + 1]:
            else:
                #print('C')
                inode_last += 1


            #print('inode_last[%i] = %s' % (isubcurve, inode_last))
            bars[:, 0] = inodes
            bars[:-1, 1] = inodes[1:]

            bars[-1, 1] = inode_last
            assert inode_last != nnodes
            bars_list.append(bars)

            n1 = bars[:, 0]
            n2 = bars[:, 1]
            #n1 = n1a
            n2a = n2
            #print "n1a = ", n1a, len(n1a)
            #print "n2a = ", n2a, len(n2a)

            if 1:
                ib = list(range(1, nbars))
                ib.append(0)

                ib = array(ib, dtype='int32')
                n1 = n1
                n3 = bars[ib, 1]
                #print "n1a = ", n1a, len(n1a)
                #print "n2a = ", n2a, len(n2a)
                #print "n1b = ", n1b, len(n1b)
                #print "n2b = ", n2b, len(n2b)

                #if 0:
                    #v1 = nodes[n2, :] - nodes[n1, :]
                    #v2 = nodes[n3, :] - nodes[n1, :]

                    #L1 = norm(v1, axis=1)
                    #L2 = norm(v2, axis=1)

                    #c = cross(v1, v2)
                    #cn = norm(c, axis=1)

                    #L1L2 = (L1 * L2)
                    #izero = where(L1L2 == 0.0)[0]
                    #L1L2[izero] = 1e-10
                    #sin_theta = cn / L1L2
                    #theta = degrees(arcsin(sin_theta))

                # convention from http://en.wikipedia.org/wiki/Triangle
                c = norm(nodes[n2, :2] - nodes[n1, :2], axis=1) # c
                a = norm(nodes[n3, :2] - nodes[n2, :2], axis=1) # a
                b = norm(nodes[n3, :2] - nodes[n1, :2], axis=1) # b
                assert len(a) == len(n1), 'wrong size...check axis'

                cos_inner = (a**2 + c**2 - b**2)/(2 * a * c)
                beta = arccos(np.clip(cos_inner, -1., 1.))
                inan = where(isnan(beta))[0]
                beta[inan] = 0.0
                i180 = where(abs(beta) > radians(beta_reverse))[0]
                beta[i180] = 0.0
                #print('beta = %s' % beta)
                #print('beta_nonzero = %s' % beta[where(beta != 0)[0]])
                #print('beta_nonzero deg = %s' % degrees(beta[where(beta != 0)[0]]))

                #if 0:
                    #for inani in inan:
                        #nids_failed = [n1[inani], n2[inani], n3[inani]]
                        #print('nodes = %s' % nids_failed)
                        #for nid in nids_failed:
                            #print('  nodes[%3i] = %s' % (nid, nodes[nid, :]))

                centroid = (nodes[n1, :] + nodes[n2, :] + nodes[n3, :]) / 3.
                xcentroid = centroid[:, 0]
                ycentroid = centroid[:, 1]
                # maybe shift the node to the centroid of the element to fix sign?
                min_xy = nodes[:, :2].min(axis=0)
                delta_xy = 2.0 * abs(min_xy)
                dx, dy = delta_xy
                self.log.debug('min_xy = %s' % min_xy)
                assert len(min_xy) == 2, min_xy

                # y/x for nodes 1, 2, and 3; find theta
                theta1g = arctan2(nodes[n1, 1] + dy, nodes[n1, 0] + dx)
                theta2g = arctan2(nodes[n2, 1] + dy, nodes[n2, 0] + dx)
                theta3g = arctan2(nodes[n3, 1] + dy, nodes[n3, 0] + dx)
                theta12g = theta2g - theta1g
                theta23g = theta3g - theta2g

                mag_theta = sign(theta12g - theta23g)
                izero = where(beta == 0.)[0]
                mag_theta[izero] = 0.
                inotzero = where(beta != 0)
                #print('i')
                #izero = where(allclose(mag_theta, 0.))[0]
                #mag_theta[izero] = 1.0
                #print('mag_theta = %s' % mag_theta)
                turn_angle = mag_theta * beta
                #turn_angle = degrees(beta)

                turn_angle_list.append(turn_angle)

            #print('inodes[%i]=%s'  % (icurve, inodes))
            #print('bars[%i]=\n%s\n'  % (isubcurve, bars))
            for bari in bars:
                n1, n2 = bari
                #print(bari, nodes[n1, :], nodes[n2, :])
            #print('nodes[%i]=\n%s\n'  % (isubcurve, nodes[n1a, :2]))
            inode0 += nnodesi
            #break
        del isubcurve
        bars = vstack(bars_list)
        if len(turn_angle_list) == 1:
            pass # turn_angle = turn_angle_list[0]
        else:
            turn_angle = hstack(turn_angle_list)
        #print('nodes = \n%s' % nodes)

        self.nodes = nodes
        self.bars = bars
        self.curves = curves
        self.subcurves = subcurves
        self.grid_bc = grid_bc
        self.grid_bcs = grid_bcs
        self.log.debug('grid_bcs = %s' % unique(grid_bcs))
        self.turn_angle = turn_angle
        sys.stdout.flush()