Example #1
0
    def mesh_it(self, rod_length = 0.5 , driver = [],mesher = [], bbox = [], density = "", visual = False, angles = False, save = []):
        """mesh_it(rod_length:float, driver, mesher, \
        bbox:[float list,float list]), density, visual:bool,
        save:string list).
        
        Function to mesh the present object(s). The rod_length
        is the desired length of the connections between the mesh nodes,
        a value which is weighted with the C function density. The bbox
        defines the outer boundary box of the mesh. The flag visual
        consents to visualise the mesh during its relaxation process,
        and it can be saved specifying the file (with format) in the save
        list.
        Possible formats are postscript file(s) ("ps" extension) (2D only),
        vtk file(s) ("vtk" extension) (included the ones created at every
        visualization step) and "pyfem" format ("dat" extension).
        The function returns the mesh data in a python list of lists
        (the content is clear once they are inspected).
        """
        
        self.rod = rod_length
        self.density = density
        if mesher == []:
            self.mesher = ocaml.mesher_defaults
        else:
            self.mesher = mesher.my_mesher

        self.__file_vtk = ""
        self.__file_ps = ""
        self.__file_dat = ""
        self.__file_png = ""
        globals()['fig_number']=0
        globals()['angles_time']=[]
        globals()['default_iterations'] = 200



        def check_save():
            """Function to check if the mesh has to be saved
            in any format.
            """

#            print "check_save"

            if len(save)>0:
                for filename in save:
                    if filename[-3:]=="dat":
                        self.__file_dat = filename
                    elif filename[-3:]=="vtk":
                        self.__file_vtk = filename
                    elif filename[-3:]==".ps":
                        self.__file_ps = filename
                    elif filename[-3:]=="png":
                        self.__file_png = filename
                    else:
                        ValueError ("wrong extension in save file name")

#            print self.__file_vtk, self.__file_ps, self.__file_dat, self.__file_png
            
        if visual: # Initialisation of mayavi if argument visual = True
#            print "load mayavi"
            import mayavi, pylab # Tk error without pylab
            self.myv = mayavi.mayavi()


        def check_vtk(nr_piece,n,mesh):
#            print "check_vtk -- 0"
            if visual or self.__file_vtk!="":
#                print "mesh_info"
                mesh_info = ocaml.mesh_plotinfo(mesh)
#                print "check_vtk -- 1"
                v = self._mesh2vtk(mesh_info,self.__file_vtk,"-"+str(nr_piece),"-"+str(n))
#                print "check_vtk -- 2"


                if visual:                   
#                    print "visual"
                    # Function executed for argument visual = True
                    self.myv.close_all()
                    vd = self.myv.open_vtk_data(v)
                    dvm = self.myv.get_current_dvm()
                    mm = dvm.get_current_module_mgr()
                    md = self.myv.load_module('SurfaceMap',0)

                    # reverse LUT
                    luthandler = mm.get_scalar_lut_handler()
                    luthandler.set_lut_red_blue()
                    
                    # display legend, vertically with shadow effect
                    luthandler.sc_bar.SetVisibility(1)
                    luthandler.sc_bar.GetTitleTextProperty().SetShadow(1)
                    luthandler.sc_bar.GetLabelTextProperty().SetShadow(1)
                    luthandler.sc_bar.GetPositionCoordinate().SetValue(0.01,0.15)
                    luthandler.sc_bar.SetOrientationToVertical()
                    luthandler.sc_bar.SetWidth(0.14)
                    luthandler.sc_bar.SetHeight(0.85)
#                    luthandler.sc_bar.SetTitle('in2circ')
                                  
                    self.myv.renwin.z_plus_view()
                    vd2 = self.myv.open_vtk_data(v)
                    dvm = self.myv.get_current_dvm()
                    mm = dvm.get_current_module_mgr()
                    md2 = self.myv.load_module('SurfaceMap',0)
                    md2.mapper.ScalarVisibilityOff()
                    md2.actor.GetProperty().SetRepresentationToWireframe()
                    self.myv.renwin.z_plus_view()
                    self.myv.Render()

                    # if angles analysis has been requested plot histogram in pylab now
                    if angles:
                        angles_data = self._findAngles(mesh_info)                        
                        n, bins, patches = pylab.hist(angles_data, range(0,180,5))               
                        pylab.xlabel('Internal angle in degrees')
                        pylab.ylabel('Number of occurrences')
                        pylab.title('Histogram of internal angles of %d triangles' % (len(mesh_info[2][2])))
                        pylab.axvline(x=60, color='r')                        
                        pylab.savefig(self.__file_png[:-4]+str(globals()['fig_number'])+'.png')
                        globals()['fig_number'] = globals()['fig_number'] + 1
                        pylab.show()    #(screws with Tk events)
                        pylab.clf()

                        # attempt to save time series of angles data for quality vs. time plot
                        # this temporary hack saves the median angle for the highest count bin
                        highest = 0
                        modal = 0
                        for i in range(len(n)):
                            if n[i] > highest:
                                highest = n[i]
                                modal = i
                        median = (bins[modal] + bins[modal-1])/2.
                        globals()['angles_time'].append(median)

                    raw_input('Hit Any Key to Continue')
        
        def no_driver(nr_piece,n,mesh):
            """Function executed for argument visual = False
            """
#            print "no_driver"
            check_vtk(nr_piece,n,mesh)
            pass


        def fun_from_driver(nr_piece,n,mesh):
            """Function that glues together the user-defined
            function and the (possible) visualisation of the
            mesh during relaxation process.
            """
            check_vtk(nr_piece,n,mesh)
#            print "*********************fun_from_driver"
            driver.driver_do(nr_piece,n,mesh)  #user-defined function

        check_save() # check if the mesh has to be saved

        if driver == []:   # no driver is given: use the default one
            self.driver = ocaml.make_mg_gendriver(globals()['default_iterations'], no_driver)
        else:
#            print self.__file_vtk
            self.driver = ocaml.make_mg_gendriver(driver.every_nr_steps,fun_from_driver)
            
        if bbox != []:  # overwrite bbox defined at object initialisation
            self.bbox = bbox

        
#        print self.bbox
#        print self.obj
        obj_length = len(self.obj) # number of objects to mesh

        raw_mesh = ocaml.mesh_bodies_raw(self.driver,self.mesher,\
                                         self.bbox[0],self.bbox[1],obj_length,\
                                         self.obj,rod_length,self.density)

        if self.__file_ps != "":
            ocaml.mesh2d_ps(raw_mesh,self.__file_ps,[50.0,50.0,300.0,300.0])            
        if self.__file_dat != "":
            ocaml.mesh_writefile(self.__file_dat,raw_mesh)


        # to display final results in visual mode
        if visual:
            mesh_info = ocaml.mesh_plotinfo(raw_mesh)
            v = self._mesh2vtk(mesh_info,self.__file_vtk)
            
            self.myv.close_all()
            vd = self.myv.open_vtk_data(v)
            dvm = self.myv.get_current_dvm()
            mm = dvm.get_current_module_mgr()
            md = self.myv.load_module('SurfaceMap',0)
            
            # reverse LUT
            luthandler = mm.get_scalar_lut_handler()
            luthandler.set_lut_red_blue()
            
            # display legend, vertically with shadow effect
            luthandler.sc_bar.SetVisibility(1)
            luthandler.sc_bar.GetTitleTextProperty().SetShadow(1)
            luthandler.sc_bar.GetLabelTextProperty().SetShadow(1)
            luthandler.sc_bar.GetPositionCoordinate().SetValue(0.01,0.15)
            luthandler.sc_bar.SetOrientationToVertical()
            luthandler.sc_bar.SetWidth(0.14)
            luthandler.sc_bar.SetHeight(0.85)
            # luthandler.sc_bar.SetTitle('in2circ')
            
            self.myv.renwin.z_plus_view()
            vd2 = self.myv.open_vtk_data(v)
            dvm = self.myv.get_current_dvm()
            mm = dvm.get_current_module_mgr()
            md2 = self.myv.load_module('SurfaceMap',0)
            md2.mapper.ScalarVisibilityOff()
            md2.actor.GetProperty().SetRepresentationToWireframe()
            self.myv.renwin.z_plus_view()
            self.myv.Render()

                        
            if self.__file_png:
                # if angles analysis has been requested plot histogram in pylab now
                if angles:
                    angles_data = self._findAngles(mesh_info)                        
                    n, bins, patches = pylab.hist(angles_data, range(0,180,5))
                    pylab.clf()
                    pylab.xlabel('Internal angle in degrees')
                    pylab.ylabel('Number of occurrences')
                    pylab.title('Histogram of internal angles of mesh triangles')
                    pylab.axvline(x=60, color='r')                        
                    pylab.savefig(self.__file_png[:-4]+str(globals()['fig_number'])+'.png')
                    globals()['fig_number'] = globals()['fig_number'] + 1
                    pylab.show()    #(screws with Tk events)

                    # also save time plot of angles
                    pylab.clf()
                    total_iterations = globals()['default_iterations']*len(globals()['angles_time'])
                    xvalues = range(0,total_iterations,globals()['default_iterations'])
                    pylab.plot(xvalues,globals()['angles_time'],'k+')
                    pylab.hold(True)
                    pylab.plot(xvalues,globals()['angles_time'])
                    pylab.xlabel('Number of iterations')
                    pylab.ylabel('Modal internal angle (2D) in degrees')
                    pylab.title('Plot of mesh quality against time')
                    pylab.savefig(self.__file_png[:-4]+'_time.png')

            raw_input('Hit Any Key to Exit.')
            
        else:
            mesh_info = ocaml.mesh_plotinfo(raw_mesh)
            raw_input('Hit Any Key to Exit.')
Example #2
0
    def __init__(self, objects = [], rod_length = 0.5, bbox = [[],[]],
                 density="", periodic = False, visual = False, fixed_points = [],
                 fun=[], fun_call_interval = 1000):

        """ Class to define the parameters for the meshing algorithm.
        mesh(
        objects:obj list              - objects to be meshed
        rod_length:float              - desired length of connection between nodes
        bbox:[float list,float list]  - outer bounding box
        density:string                - density function of nodes ditribution 
        periodic:bool                 - periodic boundary conditions in the outer box 
        visual:bool                   - use of the visualisation package
        fixed_points: float list list - set of fixed points to be used in the mesh
        fun                           - function to be called every interval steps
        fun_call_interval:int         - interval of the function calling
        ).
        
        The rod_length is the desired length of the connections between
        the mesh nodes, a value which is weighted with the density function
        (given in C code). The bbox defines the outer boundary box of the mesh.
        The function fun is executed every fun_call_interval steps and its
        arguments are

        nr_piece       =  index of the meshing object
        iteration_nr   =  number of iteration in the relaxation process
        mesh           =  mesh as a python list of lists (value returned by mesh_it())
        
        The visual flag and the periodic flag are used to visualise and impose
        periodic boundary conditions on the outer box, respectively.
        If periodic boundary conditions are used, the density function
        must respect the related contraints.
        """

        self.obj = []
        if type(objects) == types.ListType :
            for obj in objects:
                self.obj.append(obj.obj)
        else:
            raise ValueError("Error: wrong list of objects to mesh.")
        self.rod = rod_length
        self.bbox = bbox
        self.density = density
        if periodic:
            self.periodic = 1
        else:
            self.periodic = 0
        if visual:
            #import m.visual
            pass
        if fun == []:
            self.fun_driver = self._default_fun
        else:
            self.fun_driver = fun
        self.fun_call_interval = fun_call_interval

        self.fixed_points = fixed_points
        # add fixed points coming from objects
        for obj in objects:
            for pt in obj.fxd_pts:
                self.fixed += pt

        self.mesher = 0                         # flag for default/copied mesher
        self.my_mesher = ocaml.mesher_defaults  # default mesher
        self.driver = ocaml.make_mg_gendriver(self.fun_call_interval, self.extended_fun_driver)
        self.raw_mesh = []