/[escript]/branches/stage3.1/pycad/py_src/primitives.py
ViewVC logotype

Diff of /branches/stage3.1/pycad/py_src/primitives.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2944 by jfenwick, Thu Feb 4 01:42:47 2010 UTC revision 2945 by jfenwick, Wed Feb 24 00:17:46 2010 UTC
# Line 1  Line 1 
1    # -*- coding: utf-8 -*-
2    
3  ########################################################  ########################################################
4  #  #
# Line 497  class Manifold1D(PrimitiveBase): Line 498  class Manifold1D(PrimitiveBase):
498          """          """
499          return [ self.getStartPoint(), self.getEndPoint()]          return [ self.getStartPoint(), self.getEndPoint()]
500    
501    
502      def setElementDistribution(self,n,progression=1,createBump=False):      def setElementDistribution(self,n,progression=1,createBump=False):
503          """          """
504          Defines the number of elements on the line. If set it overwrites the local length setting which would be applied.          Defines the number of elements on the line. If set it overwrites the local length setting which would be applied.
# Line 1005  class CurveLoop(Primitive, PrimitiveBase Line 1007  class CurveLoop(Primitive, PrimitiveBase
1007             if not isinstance(curves[i],Manifold1D):             if not isinstance(curves[i],Manifold1D):
1008                raise TypeError("%s-th argument is not a Manifold1D object."%i)                raise TypeError("%s-th argument is not a Manifold1D object."%i)
1009         # for the curves a loop:         # for the curves a loop:
1010         used=[ False for i in curves]         #used=[ False for i in curves]
1011         self.__curves=list(curves)         self.__curves=[]
1012           for c in curves:
1013                if not c in self.__curves: self.__curves.append(c)
1014         Primitive.__init__(self)         Primitive.__init__(self)
1015         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
1016          
1017    
1018      def getCurves(self):      def getCurves(self):
1019         """         """
# Line 1066  class CurveLoop(Primitive, PrimitiveBase Line 1071  class CurveLoop(Primitive, PrimitiveBase
1071                  return True                  return True
1072         return False         return False
1073    
1074          
1075          
1076    
1077  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):  class ReverseCurveLoop(ReversePrimitive, PrimitiveBase):
1078      """      """
1079      An oriented loop of one-dimensional manifolds (= curves and arcs).      An oriented loop of one-dimensional manifolds (= curves and arcs).
# Line 1091  class ReverseCurveLoop(ReversePrimitive, Line 1099  class ReverseCurveLoop(ReversePrimitive,
1099    
1100      def __len__(self):      def __len__(self):
1101          return len(self.getUnderlyingPrimitive())          return len(self.getUnderlyingPrimitive())
   
1102  #=  #=
1103  class Manifold2D(PrimitiveBase):  class Manifold2D(PrimitiveBase):
1104      """      """
# Line 1125  class Manifold2D(PrimitiveBase): Line 1132  class Manifold2D(PrimitiveBase):
1132          """          """
1133          raise NotImplementedError()          raise NotImplementedError()
1134    
1135        def setElementDistribution(self,n,progression=1,createBump=False):
1136            """
1137            Defines the number of elements on the lines
1138    
1139            :param n: number of elements on the line
1140            :type n: ``int``
1141            :param progression: a positive progression factor
1142            :type progression: positive ``float``
1143            :param createBump: of elements on the line
1144            :type createBump: ``bool``
1145            """
1146            for i in self.getBoundary(): i.setElementDistribution(n,progression,createBump)
1147    
1148      def getPoints(self):      def getPoints(self):
1149          """          """
1150          returns a list of points used to define the boundary          returns a list of points used to define the boundary
# Line 1174  class Manifold2D(PrimitiveBase): Line 1194  class Manifold2D(PrimitiveBase):
1194          """          """
1195          applies 2D transfinite meshing to the surface.          applies 2D transfinite meshing to the surface.
1196    
1197          :param orientation: sets the orientation of the triangles. It is only used if recombination is not used.          :param orientation: sets the orientation of the triangles. It is only relevant if recombination is not used.
1198          :type orientation: `Manifold2D.LEFT`, `Manifold2D.RIGHT`, `Manifold2D.ALTERNATE`          :type orientation: `Manifold2D.LEFT`, `Manifold2D.RIGHT`, `Manifold2D.ALTERNATE`
1199          :note: Transfinite meshing can not be applied if holes are present.          :note: Transfinite meshing can not be applied if holes are present.
1200          """          """
# Line 1206  class Manifold2D(PrimitiveBase): Line 1226  class Manifold2D(PrimitiveBase):
1226             if opposite == None:  # three sides only             if opposite == None:  # three sides only
1227                  if not top.getElementDistribution()[0] == bottom.getElementDistribution()[0]: start, top, bottom= bottom, start, top                  if not top.getElementDistribution()[0] == bottom.getElementDistribution()[0]: start, top, bottom= bottom, start, top
1228             if not top.getElementDistribution() == bottom.getElementDistribution():             if not top.getElementDistribution() == bottom.getElementDistribution():
1229                  raise ValueError,"transfinite meshing requires oposite faces to be have the same element distribution."                  raise ValueError,"transfinite meshing requires opposite faces to be have the same element distribution."
1230             if not opposite == None:             if not opposite == None:
1231                 if not start.getElementDistribution()[0] == opposite.getElementDistribution()[0]:                 if not start.getElementDistribution()[0] == opposite.getElementDistribution()[0]:
1232                     raise ValueError,"transfinite meshing requires oposite faces to be have the same element distribution."                     raise ValueError,"transfinite meshing requires oposite faces to be have the same element distribution."
# Line 1244  class Manifold2D(PrimitiveBase): Line 1264  class Manifold2D(PrimitiveBase):
1264                  return (self.__points, self.__orientation)                  return (self.__points, self.__orientation)
1265              else:              else:
1266                  return None                  return None
1267                  def getPolygon(self):
1268           """
1269           Returns a list of start/end points of the 1D mainfold form the loop. If not closed and exception is thrown.
1270           """
1271           curves=self.getBoundary()
1272           s=[curves[0].getStartPoint(), curves[0].getEndPoint()]
1273           found= [ curves[0] ]
1274           restart=True
1275           while restart:
1276              restart=False
1277          for k in curves:
1278              if not k in found:
1279              if k.getStartPoint() == s[-1]:
1280                          found.append(k)
1281                          if k.getEndPoint() == s[0]:
1282                               if len(found) == len(curves):
1283                                 return s
1284                               else:
1285                     raise ValueError,"loop %s is not closed."%self.getID()
1286                  s.append(k.getEndPoint())
1287                  restart=True
1288                  break
1289          if not restart:
1290                   raise ValueError,"loop %s is not closed."%self.getID()          
1291  class RuledSurface(Primitive, Manifold2D):  class RuledSurface(Primitive, Manifold2D):
1292      """      """
1293      A ruled surface, i.e. a surface that can be interpolated using transfinite      A ruled surface, i.e. a surface that can be interpolated using transfinite
# Line 1612  class Manifold3D(PrimitiveBase): Line 1655  class Manifold3D(PrimitiveBase):
1655         Creates a three-dimensional manifold.         Creates a three-dimensional manifold.
1656         """         """
1657         PrimitiveBase.__init__(self)         PrimitiveBase.__init__(self)
1658           self.__transfinitemeshing=False
1659    
1660      def getBoundary(self):      def getBoundary(self):
1661          """          """
1662          Returns a list of the one-dimensional manifolds forming the boundary          Returns a list of the 2-dimensional manifolds forming the boundary
1663          of the volume (including holes).          of the volume (including holes).
1664          """          """
1665          raise NotImplementedError()          raise NotImplementedError()
1666    
1667        def setElementDistribution(self,n,progression=1,createBump=False):
1668            """
1669            Defines the number of elements on the lines and surfaces
1670    
1671            :param n: number of elements on the line
1672            :type n: ``int``
1673            :param progression: a positive progression factor
1674            :type progression: positive ``float``
1675            :param createBump: of elements on the line
1676            :type createBump: ``bool``
1677            """
1678            for i in self.getBoundary(): i.setElementDistribution(n,progression,createBump)
1679    
1680        def setRecombination(self, max_deviation=45*DEG):
1681            """
1682            Recombines triangular meshes on all surface into mixed triangular/quadrangular meshes. These meshes
1683            are then used to generate the volume mesh if possible. Recombination requires 3D transfinite meshing.
1684    
1685            ``max_deviation`` specifies the maximum derivation of the largest angle in the quadrangle
1686            from the right angle. Use ``max_deviation``==``None`` to switch off recombination.
1687    
1688            :param max_deviation: maximum derivation of the largest angle in the quadrangle from the right angle.
1689            :type max_deviation: ``float`` or ``None``.
1690            """
1691            if not max_deviation==None:
1692               if max_deviation<=0:
1693                    raise ValueError, "max_deviation must be positive."
1694               if max_deviation/DEG>=90:
1695                    raise ValueError, "max_deviation must be smaller than 90 DEG"
1696            for i in self.getBoundary(): i.setRecombination(max_deviation)
1697            self.setTransfiniteMeshing()
1698    
1699        def setTransfiniteMeshing(self,orientation="Left"):
1700            """
1701            applies 3D transfinite meshing to the volume and all surface. It requires transfinite meshing on all faces which will be enforced (except
1702    if ``orientation`` is equal to ``None``.
1703    
1704            :param orientation: sets the orientation of the triangles on the surfaces. It is only relevant if recombination is not used.
1705            If orientation is equal to ``None``, the transinite meshing is not applied to the surfaces but must be set by the user.
1706            :type orientation: `Manifold2D.LEFT`, `Manifold2D.RIGHT`, `Manifold2D.ALTERNATE`
1707            :note: Transfinite meshing can not be applied if holes are present.
1708            :note: only five or six surfaces may be used.
1709            :warning: The functionality of transfinite meshing without recombination is not entirely clear in `gmsh`. So please apply this method with care.
1710            """
1711            if isinstance(self, ReversePrimitive):
1712               return self.getUnderlyingPrimitive().setTransfiniteMeshing(orientation)
1713            else:
1714               if not orientation == None:
1715                  if not orientation in [ Manifold2D.LEFT, Manifold2D.RIGHT, Manifold2D.ALTERNATE]:
1716                     raise ValueError,"invalid orientation %s."%orientation
1717          
1718               if self.hasHole():
1719                 raise ValueError,"transfinite meshing cannot be appled to surfaces with a hole."
1720               b=self.getBoundary()
1721               # find a face with 3/4 Points:
1722               if len(b) == 6 :
1723                    des_len=4
1724               elif len(b) == 5:
1725                    des_len=3  
1726               else:
1727                    raise ValueError,"transfinite meshing permits 5 or 6 surface only."  
1728               # start_b=None
1729               # for l in b:
1730               #     if len(l.getPolygon()) == des_len:
1731               #          start_b = l
1732               #          break
1733               # if start_b == None:
1734               #     raise ValueError,"Expect face with %s points."%des_len
1735               # start_poly=start_b.getPolygon()
1736               # now we need to find the opposite face:
1737               # opposite = None  
1738               # for l in b:
1739               #    if all( [ not k in start_poly for k in l.getPolygon() ]):
1740               #       opposite = l
1741               #       break
1742               # if opposite == None:
1743               #     raise ValueError,"Unable to find face for transfinite interpolation."
1744               # opposite_poly=opposite.getPolygon()
1745               # if not len(opposite_poly) == des_len:
1746               #     raise ValueError,"Unable to find face for transfinite interpolation."
1747               # this needs more work to find the points!!!!
1748               points = []
1749               self.__points=points
1750               if not orientation == None:
1751                     for i in b: i.setTransfiniteMeshing(orientation)
1752               self.__transfinitemeshing=True
1753    
1754        def resetTransfiniteMeshing(self):
1755            """
1756            removes the transfinite meshing from the volume but not from the surfaces
1757            """
1758            if isinstance(self, ReversePrimitive):
1759               self.getUnderlyingPrimitive().resetTransfiniteMeshing()
1760            else:
1761               self.__transfinitemeshing=False
1762    
1763        def getTransfiniteMeshing(self):
1764            """
1765            returns the transfinite meshing setings. If transfinite meshing is not set, ``None`` is returned.
1766            
1767            :return: a tuple of the tuple of points used to define the transfinite meshing and the orientation. If no points are set the points tuple is returned as ``None``. If no transfinite meshing is not set, ``None`` is returned.
1768            :rtype: ``tuple`` of a ``tuple`` of `Point` s (or ``None``) and the orientation which is one of the values  `Manifold2D.LEFT` , `Manifold2D.RIGHT` , `Manifold2D.ALTERNATE`
1769            """
1770            if isinstance(self, ReversePrimitive):
1771               return self.getUnderlyingPrimitive().getTransfiniteMeshing()
1772            else:
1773                if self.__transfinitemeshing:
1774                    return self.__points
1775                else:
1776                    return None
1777    
1778  class Volume(Manifold3D, Primitive):  class Volume(Manifold3D, Primitive):
1779      """      """
1780      A volume with holes.      A volume with holes.
# Line 1645  class Volume(Manifold3D, Primitive): Line 1800  class Volume(Manifold3D, Primitive):
1800         Manifold3D.__init__(self)         Manifold3D.__init__(self)
1801         self.__loop=loop         self.__loop=loop
1802         self.__holes=holes         self.__holes=holes
1803           self.__transfinitemeshing=False
1804    
1805      def getHoles(self):      def getHoles(self):
1806         """         """
# Line 1697  class Volume(Manifold3D, Primitive): Line 1853  class Volume(Manifold3D, Primitive):
1853    
1854      def getBoundary(self):      def getBoundary(self):
1855          """          """
1856          Returns a list of the one-dimensional manifolds forming the boundary          Returns a list of the 2-dimensional manifolds forming the surface of the Volume (including holes).
         of the Surface (including holes).  
1857          """          """
1858          out = []+ self.getSurfaceLoop().getSurfaces()          out = []+ self.getSurfaceLoop().getSurfaces()
1859          for h in self.getHoles(): out+=h.getSurfaces()          for h in self.getHoles(): out+=h.getSurfaces()
1860          return out          return out
1861    
1862        def hasHole(self):
1863            """
1864            Returns True if a hole is present.
1865            """
1866            return len(self.getHoles())>0
1867  class PropertySet(Primitive, PrimitiveBase):  class PropertySet(Primitive, PrimitiveBase):
1868      """      """
1869      Defines a group of `Primitive` s which can be accessed through a name.      Defines a group of `Primitive` s which can be accessed through a name.

Legend:
Removed from v.2944  
changed lines
  Added in v.2945

  ViewVC Help
Powered by ViewVC 1.1.26