예제 #1
0
    def __init__(self,coords=None,elems=None,prop=None,eltype=None):
        """Initialize a new Mesh."""
        self.coords = self.elems = self.prop = self.eltype = None

        if coords is None:
            # Create an empty Mesh object
            #print "EMPTY MESH"
            return

        if elems is None:
            if hasattr(coords,'toMesh'):
                # initialize from a single object
                coords,elems = coords.toMesh()
            elif type(coords) is tuple:
                # SHOULD WE KEEP THIS ???
                coords,elems = coords

        try:
            self.coords = Coords(coords)
            if self.coords.ndim != 2:
                raise ValueError,"\nExpected 2D coordinate array, got %s" % self.coords.ndim
            self.elems = Connectivity(elems)
            if self.elems.size > 0 and (
                self.elems.max() >= self.coords.shape[0] or
                self.elems.min() < 0):
                raise ValueError,"\nInvalid connectivity data: some node number(s) not in coords array"
        except:
            raise

        self.setProp(prop)

        if eltype is None:
            self.eltype = defaultEltype(self.nplex())
        else:
            self.eltype = eltype
예제 #2
0
파일: tetgen.py 프로젝트: gunnups/pyFormex
def readSmeshFacetsBlock(fil, nfacets, nbmark):
    """Read a tetgen .smesh facets bock.

    Returns a tuple of dictionaries with plexitudes as keys:

    - elems: for each plexitude a Connectivity array
    - nrs: for each plexitude a list of element numbers in corresponding elems

    """
    elems = {}
    nrs = {}
    for i in range(nfacets):
        line = fil.readline()
        line = line.strip()
        if len(line) > 0:
            data = fromstring(line, sep=' ', dtype=int32)
            nplex = data[0]
            if nplex > 0:
                e = data[1:1 + nplex]
                # bmark currently not read
                addElem(elems, nrs, e, i, nplex)
            else:
                raise ValueError, "Invalid data line:\n%s" % line

    for np in elems:
        if np == 3:
            eltype = 'tri3'
        elif np == 4:
            eltype = 'quad4'
        else:
            eltype = None
        elems[np] = Connectivity(elems[np], eltype=eltype)
        nrs[np] = array(nrs[np])
    return elems, nrs
예제 #3
0
파일: tetgen.py 프로젝트: gunnups/pyFormex
def readElemsBlock(fil, nelems, nplex, nattr):
    """Read a tetgen elems block.

    Returns a tuple with:

    - elems: Connectivity of type 'tet4' or 'tet10'
    - nrs: the element numbers
    - attr: the element attributes

    The last can be None.
    """
    ndata = 1 + nplex + nattr
    data = fromfile(fil, sep=' ', dtype=int32,
                    count=ndata * nelems).reshape(nelems, ndata)
    nrs = data[:, 0]
    elems = data[:, 1:1 + nplex]
    if nattr > 0:
        attr = data[:, 1 + nplex:]
    else:
        attr = None
    if nplex == 4:
        eltype = 'tet4'
    elif nplex == 10:
        eltype = 'tet10'
    else:
        raise ValueError, "Unknown tetgen .ele plexitude %s" % nplex
    return Connectivity(elems, eltype=eltype), nrs, attr
예제 #4
0
    def getEntities(self, level, reduce=False):
        """Return the type and connectivity table of some element entities.

        The full list of entities with increasing dimensionality  0,1,2,3 is::

            ['points', 'edges', 'faces', 'cells' ]

        If level is negative, the dimensionality returned is relative
        to the highest dimensionality (.i.e., that of the element).
        If it is positive, it is taken absolute.

        Thus, for a 3D element type, getEntities(-1) returns the faces,
        while for a 2D element type, it returns the edges.
        For both types however, getLowerEntities(+1) returns the edges.

        The return value is a dict where the keys are element types
        and the values are connectivity tables.
        If reduce == False: there will be only one connectivity table
        and it may include degenerate elements.
        If reduce == True, an attempt is made to reduce the degenerate
        elements. The returned dict may then have multiple entries.

        If the requested entity level is outside the range 0..ndim,
        the return value is None.
        """
        if level < 0:
            level = self.ndim + level

        if level < 0 or level > self.ndim:
            return Connectivity()

        if level == 0:
            return Connectivity(arange(self.nplex()).reshape((-1, 1)),
                                eltype='point')

        elif level == self.ndim:
            return Connectivity(arange(self.nplex()).reshape((1, -1)),
                                eltype=self)

        elif level == 1:
            return self.edges

        elif level == 2:
            return self.faces
예제 #5
0
def _sanitize(ent):
    # input is Connectivity or (eltype,table)
    # output is Connectivity
    if isinstance(ent, Connectivity):
        if hasattr(ent, 'eltype'):
            return ent
        else:
            raise ValueError, "Conectivity should have an element type"
    else:
        return Connectivity(ent[1], eltype=ent[0])
예제 #6
0
파일: tetgen.py 프로젝트: gunnups/pyFormex
def readFacesBlock(fil, nelems, nbmark):
    """Read a tetgen faces block.

    Returns a a tuple with:

    - elems: Connectivity of type 'tri3'
    - nrs: face numbers
    - bmrk: face boundary marker

    The last can be None.
    """
    ndata = 1 + 3 + nbmark
    data = fromfile(fil, sep=' ', dtype=int32,
                    count=ndata * nelems).reshape(nelems, ndata)
    nrs = data[:, 0]
    elems = data[:, 1:4]
    if nbmark == 1:
        bmark = data[:, -1]
    else:
        bmark = None
    return Connectivity(elems, eltype='tri3'), nrs, bmark
예제 #7
0
    def __init__(self,
                 config=None,
                 force_net_build=False,
                 verbose=False,
                 debug=False,
                 host=None,
                 db_name=None,
                 user=None,
                 password=None):
        """Connects to the BNA database

        kwargs:
        config -- path to the config file, if not given use the default config.yaml
        force_net_build -- force a rebuild of the network even if an existing one is found
        verbose -- output useful messages
        debug -- set to debug mode
        host -- hostname or address (overrides the config file if given)
        db -- name of database on server (overrides the config file if given)
        user -- username to connect to database (overrides the config file if given)
        password -- password to connect to database (overrides the config file if given)

        return: pyBNA object
        """
        Destinations.__init__(self)
        Connectivity.__init__(self)
        Core.__init__(self)
        Conf.__init__(self)
        self.verbose = verbose
        self.debug = debug
        self.module_dir = os.path.dirname(os.path.abspath(__file__))
        if config is None:
            config = os.path.join(self.module_dir, "config.yaml")
        self.config = self.parse_config(yaml.safe_load(open(config)))
        self.config["bna"]["connectivity"]["max_detour"] = float(
            100 + self.config["bna"]["connectivity"]["max_detour"]) / 100
        self.db_connectivity_table = self.config["bna"]["connectivity"][
            "table"]
        self.net_config = self.config["bna"]["network"]

        # km/mi
        if "units" in self.config:
            if self.config.units == "mi":
                self.km = False
            elif self.config.units == "km":
                self.km = True
            else:
                raise ValueError("Invalid units \"{}\" in config".format(
                    self.config.units))
        else:
            self.km = False

        if self.verbose:
            print("")
            print("---------------pyBNA---------------")
            print("   Create and test BNA scenarios")
            print("-----------------------------------")
            print("")

        # set up db connection
        print("Connecting to database")
        if host is None:
            host = self.config["db"]["host"]
        if db_name is None:
            db_name = self.config["db"]["dbname"]
        if user is None:
            user = self.config["db"]["user"]
        if password is None:
            password = self.config["db"]["password"]
        db_connection_string = " ".join([
            "dbname=" + db_name, "user="******"host=" + host,
            "password="******"DB connection: %s" % db_connection_string)
        DBUtils.__init__(self, db_connection_string, self.verbose, self.debug)

        # srid
        if "srid" in self.config:
            self.srid = self.config["srid"]
        elif not self.debug:
            self.srid = self.get_srid(self.config.bna.blocks.table)

        # destinations
        self.destinations = dict()
        self.destination_blocks = set()
        if not self.debug:
            pass
            # self.set_destinations()

        self.sql_subs = self.make_bna_substitutions(self.config)

        if force_net_build:
            print("Building network tables in database")
            self.build_network()
        elif self.debug:
            pass
        elif not self.check_network():
            print("Network tables not found in database...building")
            self.build_network()
        elif self.verbose:
            print("Network tables found in database")
예제 #8
0
import materials
import cantilevers
import matplotlib.pyplot as plt
from scipy.interpolate import InterpolatedUnivariateSpline
from gaussian import Gaussian
from laminate_fem import LaminateFEM
from connectivity import Connectivity
import scipy.sparse as sparse
"""
"""

material = materials.PiezoMumpsMaterial()
cantilever = cantilevers.InitialCantileverFixedTip()
la = laminate_analysis.LaminateAnalysis(cantilever, material, True)
fem = LaminateFEM(cantilever, material, True, 0.01)
connectivity = Connectivity(fem.mesh)
gaussian = Gaussian(fem, fem.cantilever, 0.1)

index = 100  # the index of the pseudo-density to vary.
ps = np.arange(0.02, 1, 0.01)
g3sums = np.empty_like(ps)
netas = np.empty_like(ps)
dg3sums = np.empty_like(ps)
dnetas = np.empty_like(ps)

print('Number of points: %d' % len(ps))
pnew = la.fem.density.copy()
mdofmat = la.mdofmat
tdofmat = la.tdofmat

for i, p in enumerate(ps):
예제 #9
0
class Mesh(Geometry):
    """A mesh is a discrete geometrical model defined by nodes and elements.

    In the Mesh geometrical data model, coordinates of all points are gathered
    in a single twodimensional array 'coords' with shape (ncoords,3) and the
    individual geometrical elements are described by indices into the 'elems'
    array.
    This model has some advantages over the Formex data model, where all
    points of all element are stored by their coordinates:
    
    - compacter storage, because coordinates of coinciding points do not
      need to be repeated,
    - faster connectivity related algorithms.
    
    The downside is that geometry generating algorithms are far more complex
    and possibly slower.
    
    In pyFormex we therefore mostly use the Formex data model when creating
    geometry, but when we come to the point of exporting the geometry to
    file (and to other programs), a Mesh data model may be more adequate.

    The Mesh data model has at least the following attributes:
    
    - coords: (ncoords,3) shaped Coords array,
    - elems: (nelems,nplex) shaped array of int32 indices into coords. All
      values should be in the range 0 <= value < ncoords.
    - prop: array of element property numbers, default None.
    - eltype: string designing the element type, default None.
    
    If eltype is None, a default eltype is deived from the plexitude.

    A Mesh can be initialized by its attributes (coords,elems,prop,eltype)
    or by a single geometric object that provides a toMesh() method.
    """
    def __init__(self,coords=None,elems=None,prop=None,eltype=None):
        """Initialize a new Mesh."""
        self.coords = self.elems = self.prop = self.eltype = None

        if coords is None:
            # Create an empty Mesh object
            #print "EMPTY MESH"
            return

        if elems is None:
            if hasattr(coords,'toMesh'):
                # initialize from a single object
                coords,elems = coords.toMesh()
            elif type(coords) is tuple:
                # SHOULD WE KEEP THIS ???
                coords,elems = coords

        try:
            self.coords = Coords(coords)
            if self.coords.ndim != 2:
                raise ValueError,"\nExpected 2D coordinate array, got %s" % self.coords.ndim
            self.elems = Connectivity(elems)
            if self.elems.size > 0 and (
                self.elems.max() >= self.coords.shape[0] or
                self.elems.min() < 0):
                raise ValueError,"\nInvalid connectivity data: some node number(s) not in coords array"
        except:
            raise

        self.setProp(prop)

        if eltype is None:
            self.eltype = defaultEltype(self.nplex())
        else:
            self.eltype = eltype


    def setCoords(self,coords):
        """Replace the current coords with new ones.

        Returns a Mesh exactly like the current except for the position
        of the coordinates.
        """
        if isinstance(coords,Coords) and coords.shape == self.coords.shape:
            return Mesh(coords,self.elems,self.prop,self.eltype)
        else:
            raise ValueError,"Invalid reinitialization of Mesh coords"


    def setProp(self,prop=None):
        """Create or destroy the property array for the Mesh.

        A property array is a rank-1 integer array with dimension equal
        to the number of elements in the Mesh.
        You can specify a single value or a list/array of integer values.
        If the number of passed values is less than the number of elements,
        they wil be repeated. If you give more, they will be ignored.
        
        If a value None is given, the properties are removed from the Mesh.
        """
        if prop is None:
            self.prop = None
        else:
            prop = array(prop).astype(Int)
            self.prop = resize(prop,(self.nelems(),))
        return self


    def getProp(self):
        """Return the properties as a numpy array (ndarray)"""
        return self.prop


    def maxProp(self):
        """Return the highest property value used, or None"""
        if self.prop is None:
            return None
        else:
            return self.prop.max()


    def propSet(self):
        """Return a list with unique property values."""
        if self.prop is None:
            return None
        else:
            return unique(self.prop)


    def copy(self):
        """Return a copy using the same data arrays"""
        # SHOULD THIS RETURN A DEEP COPY?
        return Mesh(self.coords,self.elems,self.prop,self.eltype)


    def toFormex(self):
        """Convert a Mesh to a Formex.

        The Formex inherits the element property numbers and eltype from
        the Mesh. Node property numbers however can not be translated to
        the Formex data model.
        """
        return Formex(self.coords[self.elems],self.prop,self.eltype)

    
    def ndim(self):
        return 3
    def nelems(self):
        return self.elems.shape[0]
    def nplex(self):
        return self.elems.shape[1]
    def ncoords(self):
        return self.coords.shape[0]
    nnodes = ncoords
    npoints = ncoords
    def shape(self):
        return self.elems.shape

    def nedges(self):
        """Return the number of edges.

        This returns the number of rows that would be in getEdges(),
        without actually constructing the edges.
        The edges are not fused!
        """
        try:
            el = getattr(elements,self.eltype.capitalize())
            return self.nelems() * len(el.edges)
        except:
            return 0
    


    def centroids(self):
        """Return the centroids of all elements of the Mesh.

        The centroid of an element is the point whose coordinates
        are the mean values of all points of the element.
        The return value is a Coords object with nelems points.
        """
        return self.coords[self.elems].mean(axis=1)
        
    
    def getCoords(self):
        """Get the coords data."""
        return self.coords

    
    def getElems(self):
        """Get the elems data."""
        return self.elems


    def getLowerEntitiesSelector(self,level=-1,unique=False):
        """Get the entities of a lower dimensionality.

        If the element type is defined in the :mod:`elements` module,
        this returns a Connectivity table with the entities of a lower
        dimensionality. The full list of entities with increasing
        dimensionality  0,1,2,3 is::

            ['points', 'edges', 'faces', 'cells' ]

        If level is negative, the dimensionality returned is relative
        to that of the caller. If it is positive, it is taken absolute.
        Thus, for a Mesh with a 3D element type, getLowerEntities(-1)
        returns the faces, while for a 2D element type, it returns the edges.
        For bothe meshes however,  getLowerEntities(+1) returns the edges.

        By default, all entities for all elements are returned and common
        entities will appear multiple times. Specifying unique=True will 
        return only the unique ones.

        The return value may be an empty table, if the element type does
        not have the requested entities (e.g. the 'point' type).
        If the eltype is not defined, or the requested entity level is
        outside the range 0..3, the return value is None.
        """
        try:
            el = getattr(elements,self.eltype.capitalize())
        except:
            return None

        if level < 0:
            level = el.ndim + level

        if level < 0 or level > 3:
            return None

        attr = ['points', 'edges', 'faces', 'cells'][level]
        return array(getattr(el,attr))


    def getLowerEntities(self,level=-1,unique=False):
        """Get the entities of a lower dimensionality.

        If the element type is defined in the :mod:`elements` module,
        this returns a Connectivity table with the entities of a lower
        dimensionality. The full list of entities with increasing
        dimensionality  0,1,2,3 is::

            ['points', 'edges', 'faces', 'cells' ]

        If level is negative, the dimensionality returned is relative
        to that of the caller. If it is positive, it is taken absolute.
        Thus, for a Mesh with a 3D element type, getLowerEntities(-1)
        returns the faces, while for a 2D element type, it returns the edges.
        For bothe meshes however,  getLowerEntities(+1) returns the edges.

        By default, all entities for all elements are returned and common
        entities will appear multiple times. Specifying unique=True will 
        return only the unique ones.

        The return value may be an empty table, if the element type does
        not have the requested entities (e.g. the 'point' type).
        If the eltype is not defined, or the requested entity level is
        outside the range 0..3, the return value is None.
        """
        sel = self.getLowerEntitiesSelector(level)
        ent = self.elems.selectNodes(sel)
        if unique:
            ent = ent.removeDoubles()

        return ent


    def getEdges(self,unique=False):
        """Return the edges of the elements.

        This is a convenient function to create a table with the element
        edges. It is equivalent to  ```self.getLowerEntities(1,unique)```
        """
        return self.getLowerEntities(1,unique)


    def getFaces(self,unique=False):
        """Return the faces of the elements.

        This is a convenient function to create a table with the element
        faces. It is equivalent to ```self.getLowerEntities(2,unique)```
        """
        return self.getLowerEntities(2,unique)


    # ?? DOES THIS WORK FOR *ANY* MESH ??
    def getAngles(self, angle_spec=Deg):
        """Returns the angles in Deg or Rad between the edges of a mesh.
        
        The returned angles are shaped  as (nelems, n1faces, n1vertices),
        where n1faces are the number of faces in 1 element and the number of vertices in 1 face.
        """
        mf=self.getCoords()[self.getFaces()]
        el = getattr(elements,self.eltype.capitalize())
        v = mf - roll(mf,-1,axis=1)
        v=normalize(v)
        v1=-roll(v,+1,axis=1)
        angfac= arccos( dotpr(v, v1) )*180./math.pi
        return angfac.reshape(self.nelems(),len(el.faces), len(el.faces[0]))


    def getBorder(self):
        """Return the border of the Mesh.

        This returns a Connectivity table with the border of the Mesh.
        The border entities are of a lower jierarchical level than the
        mesh itself. This Connectivity can be used together with the
        Mesh coords to construct a Mesh of the border geometry.
        See also getBorderMesh.
        """
        sel = self.getLowerEntitiesSelector(-1)
        hi,lo = self.elems.insertLevel(sel)
        hiinv = hi.inverse()
        ncon = (hiinv>=0).sum(axis=1)
        brd = (ncon<=1)
        brd = lo[brd]
        return brd


    def getBorderMesh(self):
        """Return a Mesh with the border elements.

        Returns a Mesh representing the border of the Mesh.
        The new Mesh is of the next lower hierarchical level.
        """
        return Mesh(self.coords,self.getBorder())


    def report(self):
        bb = self.bbox()
        return """
Shape: %s nodes, %s elems, plexitude %s
BBox: %s, %s
Size: %s
""" % (self.ncoords(),self.nelems(),self.nplex(),bb[1],bb[0],bb[1]-bb[0])


    def __str__(self):
        return self.report() + "Coords:\n" + self.coords.__str__() +  "Elems:\n" + self.elems.__str__()


    def fuse(self,**kargs):
        """Fuse the nodes of a Meshes.

        All nodes that are within the tolerance limits of each other
        are merged into a single node.  

        The merging operation can be tuned by specifying extra arguments
        that will be passed to :meth:`Coords:fuse`.
        """
        coords,index = self.coords.fuse(**kargs)
        return Mesh(coords,index[self.elems],self.prop,self.eltype)
    

    def compact(self):
        """Remove unconnected nodes and renumber the mesh.

        Beware! This function changes the object in place.
        """
        nodes = unique1d(self.elems)
        if nodes.size == 0:
            self.__init__([],[])
        
        elif nodes.shape[0] < self.ncoords() or nodes[-1] >= nodes.size:
            coords = self.coords[nodes]
            if nodes[-1] >= nodes.size:
                elems = inverseUniqueIndex(nodes)[self.elems]
            else:
                elems = self.elems
            self.__init__(coords,elems,prop=self.prop,eltype=self.eltype)

        return self


    def select(self,selected):
        """Return a mesh with selected elements from the original.

        - `selected`: an object that can be used as an index in the
          `elems` array, e.g. a list of element numbers.
          
        Returns a Mesh with only the selected elements.
        The returned mesh is not compacted.
        """
        if len(self.elems) == 0:
            return self
        prop = self.prop
        if prop is not None:
            prop = prop[selected]
        elems = self.elems[selected]
        return Mesh(self.coords,elems,prop,self.eltype)


    def meanNodes(self,nodsel):
        """Create nodes from the existing nodes of a mesh.

        `nodsel` is a local node selector as in :meth:`selectNodes`
        Returns the mean coordinates of the points in the selector. 
        """
        elems = self.elems.selectNodes(nodsel)
        return self.coords[elems].mean(axis=1)


    def addNodes(self,newcoords,eltype=None):
        """Add new nodes to elements.

        `newcoords` is an `(nelems,nnod,3)` array of coordinates.
        Each element thus gets exactly `nnod` extra points and the result
        is a Mesh with plexitude self.nplex() + nnod.
        """
        newnodes = arange(newcoords.shape[0]).reshape(self.elems.shape[0],-1) + self.coords.shape[0]
        elems = Connectivity(concatenate([self.elems,newnodes],axis=-1))
        coords = Coords.concatenate([self.coords,newcoords])
        return Mesh(coords,elems,self.prop,eltype)


    def addMeanNodes(self,nodsel,eltype=None):
        """Add new nodes to elements by averaging existing ones.

        `nodsel` is a local node selector as in :meth:`selectNodes`
        Returns a Mesh where the mean coordinates of the points in the
        selector are added to each element, thus increasing the plexitude
        by the length of the items in the selector.
        The new element type should be set to correct value.
        """
        newcoords = self.meanNodes(nodsel)
        return self.addNodes(newcoords,eltype)


    def selectNodes(self,nodsel,eltype):
        """Return a mesh with subsets of the original nodes.

        `nodsel` is an object that can be converted to a 1-dim or 2-dim
        array. Examples are a tuple of local node numbers, or a list
        of such tuples all having the same length.
        Each row of `nodsel` holds a list of local node numbers that
        should be retained in the new connectivity table.
        """
        elems = self.elems.selectNodes(nodsel)
        prop = self.prop
        if prop is not None:
            prop = column_stack([prop]*len(nodsel)).reshape(-1)
        return Mesh(self.coords,elems,prop=prop,eltype=eltype)   

    
    def withProp(self,val):
        """Return a Mesh which holds only the elements with property val.

        val is either a single integer, or a list/array of integers.
        The return value is a Mesh holding all the elements that
        have the property val, resp. one of the values in val.
        The returned Mesh inherits the matching properties.
        
        If the Mesh has no properties, a copy with all elements is returned.
        """
        if self.prop is None:
            return Mesh(self.coords,self.elems,eltype=self.eltype)
        elif type(val) == int:
            return Mesh(self.coords,self.elems[self.prop==val],val,self.eltype)
        else:
            t = zeros(self.prop.shape,dtype=bool)
            for v in asarray(val).flat:
                t += (self.prop == v)
            return Mesh(self.coords,self.elems[t],self.prop[t],self.eltype)
            

    def splitProp(self):
        """Partition aMesh according to its prop values.

        Returns a dict with the prop values as keys and the corresponding
        partitions as values. Each value is a Mesh instance.
        It the Mesh has no props, an empty dict is returned.
        """
        if self.prop is None:
            return {}
        else:
            return dict([(p,self.withProp(p)) for p in self.propSet()])
    

    def convert(self,totype):
        fromtype = self.eltype

        strategy = _conversions_[fromtype].get(totype,None)

        while not type(strategy) is list:
            # This allows for aliases in the conversion database
            strategy = _conversions_[fromtype].get(strategy,None)
            if strategy is None:
                raise ValueError,"Don't know how to convert %s -> %s" % (fromtype,totype)

        # 'r' and 'v' steps can only be the first and only step
        steptype,stepdata = strategy[0]
        if steptype == 'r':
            # Randomly convert elements to one of the types in list
            return self.convertRandom(stepdata)
        elif steptype == 'v':
            return self.convert(stepdata).convert(totype)

        # Execute a strategy
        mesh = self
        totype = totype.split('-')[0]
        for step in strategy:
            #print "STEP: %s" % str(step)
            steptype,stepdata = step

            if steptype == 'm':
                mesh = mesh.addMeanNodes(stepdata,totype)
                
            elif steptype == 's':
                mesh = mesh.selectNodes(stepdata,totype)

            else:
                raise ValueError,"Unknown conversion step type '%s'" % steptype

        return mesh


    def splitRandom(self,n):
        """Split a mesh in n parts, distributing the elements randomly."""
        sel = random.randint(0,n,(self.nelems()))
        return [ self.select(sel==i) for i in range(n) if i in sel ]


    def convertRandom(self,choices):
        """Convert choosing randomly between choices"""
        ml = self.splitRandom(len(choices))
        ml = [ m.convert(c) for m,c in zip(ml,choices) ]
        prop = self.prop
        if prop is not None:
            prop = concatenate([m.prop for m in ml])
        elems = concatenate([m.elems for m in ml],axis=0)
        eltype = set([m.eltype for m in ml])
        if len(eltype) > 1:
            raise RuntimeError,"Invalid choices for random conversions"
        eltype = eltype.pop()
        return Mesh(self.coords,elems,prop,eltype)


    def reduceDegenerate(self,eltype=None):
        """Reduce degenerate elements to lower plexitude elements.

        This will try to reduce the degenerate elements of the mesh to elements
        of a lower plexitude. If a target element type is given, only the matching
        recuce scheme is tried. Else, all the target element types for which
        a reduce scheme from the Mesh eltype is available, will be tried.

        The result is a list of Meshes of which the last one contains the
        elements that could not be reduced and may be empty.
        Property numbers propagate to the children. 
        """
        strategies = _reductions_.get(self.eltype,{})
        if eltype is not None:
            s = strategies.get(eltype,[])
            if s:
                strategies = {eltype:s}
            else:
                strategies = {}
        if not strategies:
            return [self]

        m = self
        ML = []

        for eltype in strategies:
            #print "REDUCE TO %s" % eltype

            elems = []
            prop = []
            for conditions,selector in strategies[eltype]:
                e = m.elems
                cond = array(conditions)
                #print "TRYING",cond
                #print e
                w = (e[:,cond[:,0]] == e[:,cond[:,1]]).all(axis=1)
                #print "Matching elems: %s" % where(w)[0]
                sel = where(w)[0]
                if len(sel) > 0:
                    elems.append(e[sel][:,selector])
                    if m.prop is not None:
                        prop.append(m.prop[sel])
                    # remove the reduced elems from m
                    m = m.select(~w)

                    if m.nelems() == 0:
                        break

            if elems:
                elems = concatenate(elems)
                if prop:
                    prop = concatenate(prop)
                else:
                    prop = None
                #print elems
                #print prop
                ML.append(Mesh(m.coords,elems,prop,eltype))

            if m.nelems() == 0:
                break

        ML.append(m)

        return ML


    def splitDegenerate(self,autofix=True):
        """Split a Mesh in degenerate and non-degenerate elements.

        If autofix is True, the degenerate elements will be tested against
        known degeneration patterns, and the matching elements will be
        transformed to non-degenerate elements of a lower plexitude.

        The return value is a list of Meshes. The first holds the
        non-degenerate elements of the original Mesh. The last holds
        the remaining degenerate elements.
        The intermediate Meshes, if any, hold elements
        of a lower plexitude than the original. These may still contain
        degenerate elements.
        """
        deg = self.elems.testDegenerate()
        M0 = self.select(~deg)
        M1 = self.select(deg)
        if autofix:
            ML = [M0] + M1.reduceDegenerate()
        else:
            ML = [M0,M1]
            
        return ML


    def renumber(self,order='elems'):
        """Renumber the nodes of a Mesh in the specified order.

        order is an index with length equal to the number of nodes. The
        index specifies the node number that should come at this position.
        Thus, the order values are the old node numbers on the new node
        number positions.

        order can also be a predefined value that will generate the node
        index automatically:
        - 'elems': the nodes are number in order of their appearance in the
          Mesh connectivity.
        """
        if order == 'elems':
            order = renumberIndex(self.elems)
        newnrs = inverseUniqueIndex(order)
        return Mesh(self.coords[order],newnrs[self.elems],prop=self.prop,eltype=self.eltype)
 

    def extrude(self,n,step=1.,dir=0,autofix=True):
        """Extrude a Mesh in one of the axes directions.

        Returns a new Mesh obtained by extruding the given Mesh
        over n steps of length step in direction of axis dir.
        The returned Mesh has double plexitude of the original.

        This function is usually used to extrude points into lines,
        lines into surfaces and surfaces into volumes.
        By default it will try to fix the connectivity ordering where
        appropriate. If autofix is switched off, the connectivities
        are merely stacked, and the user may have to fix it himself.

        Currently, this function correctly transforms: point1 to line2,
        line2 to quad4, tri3 to wedge6, quad4 to hex8.
        """
        nplex = self.nplex()
        coord2 = self.coords.translate(dir,n*step)
        M = connectMesh(self,Mesh(coord2,self.elems),n)

        if autofix and nplex == 2:
            # fix node ordering for line2 to quad4 extrusions
            M.elems[:,-nplex:] = M.elems[:,-1:-(nplex+1):-1].copy()

        if autofix:
            M.eltype = defaultEltype(M.nplex())

        return M


    def revolve(self,n,axis=0,angle=360.,around=None,autofix=True):
        """Revolve a Mesh around an axis.

        Returns a new Mesh obtained by revolving the given Mesh
        over an angle around an axis in n steps, while extruding
        the mesh from one step to the next.

        This function is usually used to extrude points into lines,
        lines into surfaces and surfaces into volumes.
        By default it will try to fix the connectivity ordering where
        appropriate. If autofix is switched off, the connectivities
        are merely stacked, and the user may have to fix it himself.

        Currently, this function correctly transforms: point1 to line2,
        line2 to quad4, tri3 to wedge6, quad4 to hex8.
        """
        nplex = self.nplex()
        angles = arange(n+1) * angle / n
        coordL = [ self.coords.rotate(angle=a,axis=axis,around=around) for a in angles ]
        ML = [ Mesh(x,self.elems) for x in coordL ]

        n1 = n2 = eltype = None

        if autofix and nplex == 2:
            # fix node ordering for line2 to quad4 revolutions
            n1 = [0,1]
            n2 = [1,0]

        if autofix:
            eltype = defaultEltype(2*self.nplex())

        CL = [ connectMesh(m1,m2,1,n1,n2,eltype) for (m1,m2) in zip(ML[:-1],ML[1:]) ]
        return Mesh.concatenate(CL)


    def sweep(self,path,autofix=True,**kargs):
        """Sweep a mesh along a path, creating an extrusion

        Returns a new Mesh obtained by sweeping the given Mesh
        over a path.
        The returned Mesh has double plexitude of the original.
        The operation is similar to the extrude() method, but the path
        can be any 3D curve.
        
        This function is usually used to extrude points into lines,
        lines into surfaces and surfaces into volumes.
        By default it will try to fix the connectivity ordering where
        appropriate. If autofix is switched off, the connectivities
        are merely stacked, and the user may have to fix it himself.

        Currently, this function correctly transforms: point1 to line2,
        line2 to quad4, tri3 to wedge6, quad4 to hex8.
        """
        nplex = self.nplex()
        seq = sweepCoords(self.coords,path,**kargs)
        ML = [ Mesh(x,self.elems) for x in seq ]
        M = connectMeshSequence(ML)
        #print M

        if autofix and nplex == 2:
            # fix node ordering for line2 to quad4 extrusions
            M.elems[:,-nplex:] = M.elems[:,-1:-(nplex+1):-1].copy()

        if autofix:
            M.eltype = defaultEltype(M.nplex())

        return M


    @classmethod
    def concatenate(clas,meshes,**kargs):
        """Concatenate a list of meshes of the same plexitude and eltype

        Merging of the nodes can be tuned by specifying extra arguments
        that will be passed to :meth:`Coords:fuse`.
        """
        nplex = set([ m.nplex() for m in meshes ])
        if len(nplex) > 1:
            raise ValueError,"Cannot concatenate meshes with different plexitude: %s" % str(nplex)
        eltype = set([ m.eltype for m in meshes if m.eltype is not None ])
        if len(eltype) > 1:
            raise ValueError,"Cannot concatenate meshes with different eltype: %s" % str(eltype)
        if len(eltype) == 1:
            eltype = eltype.pop()
        else:
            eltype = None
            
        prop = [m.prop for m in meshes]
        if None in prop:
            prop = None
        else:
            prop = concatenate(prop)
            
        coords,elems = mergeMeshes(meshes,**kargs)
        elems = concatenate(elems,axis=0)
        #print coords,elems,prop,eltype
        return Mesh(coords,elems,prop,eltype)

 
    # Test and clipping functions
    

    def test(self,nodes='all',dir=0,min=None,max=None,atol=0.):
        """Flag elements having nodal coordinates between min and max.

        This function is very convenient in clipping a TriSurface in a specified
        direction. It returns a 1D integer array flagging (with a value 1 or
        True) the elements having nodal coordinates in the required range.
        Use where(result) to get a list of element numbers passing the test.
        Or directly use clip() or cclip() to create the clipped TriSurface
        
        The test plane can be defined in two ways, depending on the value of dir.
        If dir == 0, 1 or 2, it specifies a global axis and min and max are
        the minimum and maximum values for the coordinates along that axis.
        Default is the 0 (or x) direction.

        Else, dir should be compaitble with a (3,) shaped array and specifies
        the direction of the normal on the planes. In this case, min and max
        are points and should also evaluate to (3,) shaped arrays.
        
        nodes specifies which nodes are taken into account in the comparisons.
        It should be one of the following:
        
        - a single (integer) point number (< the number of points in the Formex)
        - a list of point numbers
        - one of the special strings: 'all', 'any', 'none'
        
        The default ('all') will flag all the elements that have all their
        nodes between the planes x=min and x=max, i.e. the elements that
        fall completely between these planes. One of the two clipping planes
        may be left unspecified.
        """
        if min is None and max is None:
            raise ValueError,"At least one of min or max have to be specified."

        f = self.coords[self.elems]
        if type(nodes)==str:
            nod = range(f.shape[1])
        else:
            nod = nodes

        if type(dir) == int:
            if not min is None:
                T1 = f[:,nod,dir] > min
            if not max is None:
                T2 = f[:,nod,dir] < max
        else:
            if min is not None:
                T1 = f.distanceFromPlane(min,dir) > -atol
            if max is not None:
                T2 = f.distanceFromPlane(max,dir) < atol

        if min is None:
            T = T2
        elif max is None:
            T = T1
        else:
            T = T1 * T2

        if len(T.shape) == 1:
            return T
        
        if nodes == 'any':
            T = T.any(axis=1)
        elif nodes == 'none':
            T = (1-T.any(1)).astype(bool)
        else:
            T = T.all(axis=1)
        return T


    def clip(self,t):
        """Return a TriSurface with all the elements where t>0.

        t should be a 1-D integer array with length equal to the number
        of elements of the TriSurface.
        The resulting TriSurface will contain all elements where t > 0.
        """
        return self.select(t>0)


    def cclip(self,t):
        """This is the complement of clip, returning a TriSurface where t<=0.
        
        """
        return self.select(t<=0)


    def clipAtPlane(self,p,n,nodes='any',side='+'):
        """Return the Mesh clipped at plane (p,n).

        This is a convenience function returning the part of the Mesh
        at one side of the plane (p,n)
        """
        if side == '-':
            n = -n
        return self.clip(self.test(nodes=nodes,dir=n,min=p))

    # ?? IS THIS DEFINED FOR *ANY* MESH ??
    def equiAngleSkew(self):
        """Returns the equiAngleSkew of the elements, a mesh quality parameter .
       
      It quantifies the skewness of the elements: normalize difference between
      the worst angle in each element and the ideal angle (angle in the face 
      of an equiangular element, qe).
      """
        eang=self.getAngles(Deg)
        eangsh= eang.shape
        eang= eang.reshape(eangsh[0], eangsh[1]*eangsh[2])
        eang.max(axis=1), eang.min(axis=1)
        eangMax, eangmin=eang.max(axis=1), eang.min(axis=1)
        el = getattr(elements,self.eltype.capitalize())
        nedginface= len( el.faces[0] )
        qe=180.*(nedginface-2.)/nedginface
        extremeAngles= [ (eangMax-qe)/(180.-qe), (qe-eangmin)/qe ]
        return array(extremeAngles).max(axis=0)
예제 #10
0
def createFrameModel():
    """Create the Finite Element Model.

    It is supposed here that the Geometry has been created and is available
    as a global variable F.
    """
    wireframe()
    lights(False)
    
    # Turn the Formex structure into a TriSurface
    # This guarantees that element i of the Formex is element i of the TriSurface
    S = TriSurface(F)
    nodes = S.coords
    elems = S.elems  # the triangles

    # Create edges and faces from edges
    print "The structure has %s nodes, %s edges and %s faces" % (S.ncoords(),S.nedges(),S.nfaces())

    # Create the steel structure
    E = Formex(nodes[S.getEdges()])
    clear()
    draw(E)
    
    # Get the tri elements that are part of a quadrilateral:
    prop = F.prop
    quadtri = S.getFaceEdges()[prop==6]
    nquadtri = quadtri.shape[0]
    print "%s triangles are part of quadrilateral faces" % nquadtri
    if nquadtri > 0:
        # Create triangle definitions of the quadtri faces
        tri = Connectivity.tangle(quadtri,S.getEdges())
        D = Formex(nodes[tri])
        clear()
        flatwire()
        draw(D,color='yellow')

    conn = connections(quadtri)
    print conn

    # Filter out the single connection edges
    internal = [ c[0] for c in conn if len(c[1]) > 1 ]
    print "Internal edges in quadrilaterals: %s" % internal
    
    E = Formex(nodes[S.getEdges()],1)
    E.prop[internal] = 6
    wireframe()
    clear()
    draw(E)

    # Remove internal edges
    tubes = S.getEdges()[E.prop != 6]

    print "Number of tube elements after removing %s internals: %s" % (len(internal),tubes.shape[0])

    D = Formex(nodes[tubes],1)
    clear()
    draw(D)

    # Beam section and material properties
    b = 60
    h = 100
    t = 4
    b1 = b-2*t
    h1 = h-2*t
    A = b*h - b1*h1
    print b*h**3
    I1 = (b*h**3 - b1*h1**3) / 12
    I2 = (h*b**3 - h1*b1**3) / 12
    I12 = 0
    J = 4 * A**2 / (2*(b+h)/t)

    tube = { 
        'name':'tube',
        'cross_section': A,
        'moment_inertia_11': I1,
        'moment_inertia_22': I2,
        'moment_inertia_12': I12,
        'torsional_constant': J
        }
    steel = {
        'name':'steel',
        'young_modulus' : 206000,
        'shear_modulus' : 81500,
        'density' : 7.85e-9,
        }
    print tube
    print steel

    tubesection = ElemSection(section=tube,material=steel)

    # Calculate the nodal loads

    # Area of triangles
    area,normals = S.areaNormals()
    print "Area:\n%s" % area
    # compute bar lengths
    bars = nodes[tubes]
    barV = bars[:,1,:] - bars[:,0,:]
    barL = sqrt((barV*barV).sum(axis=-1))
    print "Member length:\n%s" % barL


    ### DEFINE LOAD CASE (ask user) ###
    res = askItems([('Steel',True),
                    ('Glass',True),
                    ('Snow',False),
                    ('Solver',None,'select',['Calpy','Abaqus']),
                    ])
    if not res:
        return

    nlc = 0
    for lc in [ 'Steel','Glass','Snow' ]:
        if res[lc]:
            nlc += 1 
    NODLoad = zeros((nlc,S.ncoords(),3))

    nlc = 0
    if res['Steel']:
        # the STEEL weight
        lwgt = steel['density'] * tube['cross_section'] * 9810  # mm/s**2
        print "Weight per length %s" % lwgt
        # assemble steel weight load
        for e,L in zip(tubes,barL):
            NODLoad[nlc,e] += [ 0., 0., - L * lwgt / 2 ]
        nlc += 1
        
    if res['Glass']:
        # the GLASS weight
        wgt = 450e-6 # N/mm**2
        # assemble uniform glass load
        for e,a in zip(S.elems,area):
            NODLoad[nlc,e] += [ 0., 0., - a * wgt / 3 ]
        nlc += 1
        
    if res['Snow']:
        # NON UNIFORM SNOW
        fn = 'hesperia-nieve.prop'
        snowp = fromfile(fn,sep=',')
        snow_uniform = 320e-6 # N/mm**2
        snow_non_uniform = { 1:333e-6, 2:133e-6, 3:133e-6, 4:266e-6, 5:266e-6, 6:667e-6 }

        # assemble non-uniform snow load
        for e,a,p in zip(S.elems,area,snowp):
            NODLoad[nlc,e] += [ 0., 0., - a * snow_non_uniform[p] / 3]
        nlc += 1

    # For Abaqus: put the nodal loads in the properties database
    print NODLoad
    PDB = PropertyDB()
    for lc in range(nlc):
        for i,P in enumerate(NODLoad[lc]):
            PDB.nodeProp(tag=lc,set=i,cload=[P[0],P[1],P[2],0.,0.,0.])

    # Get support nodes
    botnodes = where(isClose(nodes[:,2], 0.0))[0]
    bot = nodes[botnodes]
    pf.message("There are %s support nodes." % bot.shape[0])

    # Upper structure
    nnodes = nodes.shape[0]              # node number offset
    ntubes = tubes.shape[0]              # element number offset
    
    PDB.elemProp(set=arange(ntubes),section=tubesection,eltype='FRAME3D')    
    
    # Create support systems (vertical beams)
    bot2 = bot + [ 0.,0.,-200.]         # new nodes 200mm below bot
    botnodes2 = arange(botnodes.shape[0]) + nnodes  # node numbers
    nodes = concatenate([nodes,bot2])
    supports = column_stack([botnodes,botnodes2])
    elems = concatenate([tubes,supports])
    ## !!!
    ## THIS SHOULD BE FIXED !!!
    supportsection = ElemSection(material=steel,section={ 
        'name':'support',
        'cross_section': A,
        'moment_inertia_11': I1,
        'moment_inertia_22': I2,
        'moment_inertia_12': I12,
        'torsional_constant': J
        })
    PDB.elemProp(set=arange(ntubes,elems.shape[0]),section=supportsection,eltype='FRAME3D')

    # Finally, the botnodes2 get the support conditions
    botnodes = botnodes2

##     # Radial movement only
##     np_fixed = NodeProperty(1,bound=[0,1,1,0,0,0],coords='cylindrical',coordset=[0,0,0,0,0,1])
    
##     # No movement, since we left out the ring beam
##     for i in botnodes:
##         NodeProperty(i,bound=[1,1,1,0,0,0],coords='cylindrical',coordset=[0,0,0,0,0,1])

##     np_central_loaded = NodeProperty(3, displacement=[[1,radial_displacement]],coords='cylindrical',coordset=[0,0,0,0,0,1])
##     #np_transf = NodeProperty(0,coords='cylindrical',coordset=[0,0,0,0,0,1])
    
    # Draw the supports
    S = connect([Formex(bot),Formex(bot2)])
    draw(S,color='black')

    if res['Solver'] == 'Calpy':
        fe_model = Dict(dict(solver='Calpy',nodes=nodes,elems=elems,prop=PDB,loads=NODLoad,botnodes=botnodes,nsteps=nlc))
    else:
        fe_model = Dict(dict(solver='Abaqus',nodes=nodes,elems=elems,prop=PDB,botnodes=botnodes,nsteps=nlc))
    export({'fe_model':fe_model})
    print "FE model created and exported as 'fe_model'"
예제 #11
0
from scipy.interpolate import InterpolatedUnivariateSpline
from gaussian import Gaussian
from laminate_fem import LaminateFEM
from connectivity import Connectivity
import scipy.sparse as sparse


"""
"""


material = materials.PiezoMumpsMaterial()
cantilever = cantilevers.InitialCantileverFixedTip()
la = laminate_analysis.LaminateAnalysis(cantilever, material, True)
fem = LaminateFEM(cantilever, material, True)
connectivity = Connectivity(fem.mesh)
gaussian = Gaussian(fem, fem.cantilever, 0.1)

index = 100  # the index of the pseudo-density to vary.
ps = np.arange(0.02, 1, 0.01)
netas = np.empty_like(ps)
dnetas = np.empty_like(ps)
dnn = np.empty_like(ps)


print('Number of points: %d' % len(ps))
pnew = la.fem.density.copy()
tau_all, tau_free = la.connectivity.thermal_analysis()
mu = la.connectivity.get_connectivity_penalty(tau_all) 
guu = gaussian.get_operator()
mdofmat = la.mdofmat
예제 #12
0
파일: dxf_menu.py 프로젝트: dladd/pyFormex
def endPoints(parts):
    """Find the end points of all parts"""
    ep = Coords.concatenate([ p.coords[[0,-1]] for p in parts ])
    endpoints, ind = ep.fuse()
    ind = Connectivity(ind.reshape(-1,2))
    return endpoints,ind
예제 #13
0
""""
  D0 = GPIO16;
  D1 = GPIO5;
  D2 = GPIO4;
  D3 = GPIO0;
  D4 = GPIO2;
  D5 = GPIO14;
  D6 = GPIO12;
  D7 = GPIO13;
  D8 = GPIO15;
  D9 = GPIO3;
  D10 = GPIO1;
  LED_BUILTIN = GPIO16
"""
from connectivity import Connectivity

sv = Connectivity()

if not sv.backup():
    sv.server()
    sv.update()
sv.wifi()

gc.collect()
예제 #14
0
    def GetHull(self):
        self.find_extreme_points()
        faces = self.find_simplex()
        connectivity = Connectivity(faces)
        dupPoints = set()
        vert_faces = [None] * len(self.mesh.verts)
        for i in range(len(self.mesh.verts)):
            for f in faces:
                if f.is_dup(i):
                    dupPoints.add(i)
                    break
            if i in dupPoints:
                continue
            for f in faces:
                if f.add_point(i):
                    if vert_faces[i] == None:
                        vert_faces[i] = set()
                    vert_faces[i].add(f)

        finalFaces = FaceSet(self.mesh)
        donePoints = set()

        iter = -1
        bw = None

        while len(faces):
            iter += 1
            if self.dump_faces:
                bw = BinaryWriter(open(f"/tmp/quickhull-{iter:05d}.bin", "wb"))
                self.mesh.write(bw)
                faces.write(bw)
                finalFaces.write(bw)
            f = faces.pop()
            if not f.vispoints:
                finalFaces.add(f)
                iter -= 1
                continue
            point = f.highest_point
            if f.dist(point) < 1e-12:  #FIXME epsilon varies with data
                # the highest point is essentially on the face (possibly to
                # the side), so all points are on the face. Thus, this face
                # is done
                for p in f.vispoints:
                    vert_faces[p].remove(f)
                f.vispoints.clear()
                finalFaces.add(f)
                iter -= 1
                continue
            litFaces = connectivity.light_faces(f, point, vert_faces)
            vispoints = connectivity.remove(litFaces)
            #print(vispoints)
            for p in vispoints:
                vert_faces[p] -= litFaces.faces
            if bw:
                bw.write_int(point)
                litFaces.write(bw)
            horizonEdges = litFaces.find_outer_edges()
            newFaces = FaceSet(self.mesh)
            for e in horizonEdges:
                if e.touches_point(point):
                    re = e.reverse
                    t = connectivity[re]
                    splitEdge = t.find_edge(re)
                    if splitEdge >= 0:
                        self.split_triangle(t, splitEdge, point, connectivity,
                                            vert_faces)
                else:
                    tri = Triangle(self.mesh, e.a, e.b, point)
                    newFaces.add(tri)
                    connectivity.add(tri)
            donePoints.clear()
            for lf in litFaces:
                for p in lf.vispoints:
                    if p in donePoints:
                        continue
                    donePoints.add(p)
                    if vert_faces[p] == None:
                        vert_faces[p] = set()
                    for nf in newFaces:
                        if nf.is_dup(p):
                            dupPoints.add(p)
                            p = -1
                            break
                    if p < 0:
                        continue
                    for nf in newFaces:
                        if nf.add_point(p):
                            vert_faces[p].add(nf)
            for p, vf in enumerate(vert_faces):
                if not vf or p in donePoints:
                    continue
                donePoints.add(p)
                for nf in newFaces:
                    if nf.add_point(p):
                        vert_faces[p].add(nf)
            if bw:
                newFaces.write(bw)
            for nf in set(newFaces.faces):
                if nf.vispoints:
                    faces.add(nf)
                else:
                    finalFaces.add(nf)
            if bw:
                bw.close()
                bw = None
            if connectivity.error:
                vis = set()
                for lf in litFaces:
                    for vp in lf.vispoints:
                        vis.add(vp)
                for lf in litFaces:
                    dist1 = 1e38
                    dist2 = 1e38
                    for i in range(3):
                        d = lf.edges[i].distance(point)
                        if d < dist1:
                            dist1 = d
                        v = self.mesh.verts[point]
                        v = sub(v, self.mesh.verts[lf.edges[i].a])
                        d = sqrt(dot(v, v))
                        if d < dist2:
                            dist2 = d
                break
        if self.dump_faces and not connectivity.error:
            iter += 1
            bw = BinaryWriter(open(f"/tmp/quickhull-{iter:05d}.bin", "wb"))
            self.mesh.write(bw)
            faces.write(bw)
            finalFaces.write(bw)
            bw.write_int(-1)
            bw.write_int(0)
            bw.write_int(0)
            bw.close()
        self.error = connectivity.error
        return finalFaces
예제 #15
0
def endPoints(parts):
    """Find the end points of all parts"""
    ep = Coords.concatenate([p.coords[[0, -1]] for p in parts])
    endpoints, ind = ep.fuse()
    ind = Connectivity(ind.reshape(-1, 2))
    return endpoints, ind
예제 #16
0
    def main_menu(self, token):
        self.token = token

        main_answer = questionary.select(
            "What do you want to do?",
            choices=[
                'Connectivity',
                'Device Setting',
                'User Management',
                'Current Status',
                'Logout'
            ]).ask()  # returns value of selection

        if(main_answer == 'Connectivity'):
            connectivity_answer = self.connectivity_menu()

            if(connectivity_answer == 'Connect'):
                connector = input("Enter Connector: ")
                adaptor = input("Enter Adaptor: ")

                date_time = input(
                    "Enter Date and Time: (format: 2019-Aug-28 10:10:00)\n")

                a = Connectivity()
                a.connect(connector, adaptor, date_time, self.token)

            elif(connectivity_answer == 'Disconnect'):
                connector = input("Enter Connector: ")
                adaptor = input("Enter Adaptor: ")

                date_time = input(
                    "Enter Date and Time: (format: 2019-Aug-28 10:10:00)\n")

                a = Connectivity()
                a.recovery(connector, adaptor, date_time, self.token)

            elif(connectivity_answer == 'Recovery'):
                connector = input("Enter Connector: ")
                adaptor = input("Enter Adaptor: ")

                date_time = input(
                    "Enter Date and Time: (format: 2019-Aug-28 10:10:00)\n")

                a = Connectivity()
                a.disconnect(connector, adaptor, date_time, self.token)

            elif(connectivity_answer == 'Calibrate'):
                connector = input("Enter Connector: ")
                adaptor = input("Enter Adaptor: ")

                date_time = input(
                    "Enter Date and Time: (format: 2019-Aug-28 10:10:00)\n")

                a = Connectivity()
                a.calibrate(connector, adaptor, date_time, self.token)

            elif(connectivity_answer == 'Queue Management'):
                a = Connectivity()
                a.queue_manage(self.token)

        elif(main_answer == 'Device Setting'):
            print('2')
        elif(main_answer == 'User Management'):
            print('3')
        elif(main_answer == 'Current Status'):
            print('4')
        elif(main_answer == 'Logout'):
            print('--Goodbye--')
            return -1
        return 0