Source code for sfepy.mesh.femlab

import math

import geom_tools as geom

[docs]def conv(x): s="[" for i in x: s+=str(i)+"," return s[:-1]+"]"
[docs]def conv2(x): s="" for i in x: s+=i+"," return s[:-1]
[docs]def conv3(x): s="" for i in x: s+="'"+i+"'," return s[:-1]
[docs]def conv4(a,b,c): s="[" for i in a: s+=str(i)+" " s=s[:-1]+"; " for i in b: s+=str(i)+" " s=s[:-1]+"; " for i in c: s+=str(i)+" " return s[:-1]+"]"
[docs]def axissym(a,b,c): "a,b ... line. c ... center" d=[(ai+bi)/2.-ci for ai,bi,ci in zip(a,b,c)] dn=math.sqrt(d[0]**2+d[1]**2+d[2]**2) return [ci+di+0.1*di/dn for ci,di in zip(c,d)]
[docs]def femlabsurface3_old(f,n,p): #fucking femlab - there is a bug in face3 for some points assert len(p)==3 a=[y[0] for y in p] b=[y[1] for y in p] c=[y[2] for y in p] return (f+"=face3(%s',%s',%s')\n")%(n,conv(a),conv(b),conv(c))
[docs]def curve2(f,p1,p2): return "%s=curve2(%s,%s);\n"%(f,conv([p1[0],p2[0]]),conv([p1[1],p2[1]]))
[docs]def getp3(p1,p2,p3): import math a=norm2(vec(p2,p3)) b=norm2(vec(p1,p3)) c=norm2(vec(p1,p2)) cosphi=(b**2+c**2-a**2)/(2*b*c) if cosphi>1.0: cosphi=1.0 return [b*cosphi, b*math.sqrt(1-cosphi**2)]
[docs]def femlabsurface3(f,n,p): assert len(p)==3 variable=f%n f1=variable+"f1" f2=variable+"f2" f3=variable+"f3" g4=variable+"g4" s="" p1=[0,0] p2=[norm2(vec(p[1],p[0])),0] p3=getp3(p[0],p[1],p[2]) s+=curve2(f1,p1,p2) s+=curve2(f2,p2,p3) s+=curve2(f3,p3,p1) s+="%s=geomcoerce('solid',{%s,%s,%s});\n"%(g4,f1,f2,f3) a=[y[0] for y in p] b=[y[1] for y in p] c=[y[2] for y in p] # print p,norm2(crossproduct(vec(p[0],p[1]), vec(p[0],p[2]))) s+="%s=embed(%s,'Wrkpln',%s);\n"%(variable,g4,conv4(a,b,c)) return s
[docs]def femlabline(f,n,p): assert len(p)==2 a=[y.getxyz()[0] for y in p] b=[y.getxyz()[1] for y in p] c=[y.getxyz()[2] for y in p] return (f+"=curve3(%s,%s,%s)\n")%(n,conv(a),conv(b),conv(c))
[docs]def triangulate2(points): if len(points)==3: return (points,) if len(points)==4: return ( (points[0],points[1],points[2]), (points[0],points[2],points[3]) ) import Polygon q=Polygon.Polygon(points) strips=Polygon.TriStrip(q) tri=[] for t in strips: for n in range(len(t)-2): tri.append((t[n],t[n+1],t[n+2])) return tri
[docs]def triangulate(points): from poly import poly # if len(points)>3: # print "-"*60 # print points # print poly.triangulate(points) # print "-"*60 return poly.triangulate(points)
[docs]def crossproduct(a,b): return (a[1]*b[2]-a[2]*b[1], a[2]*b[0]-a[0]*b[2], a[0]*b[1]-a[1]*b[0])
[docs]def norm2(x): import math return math.sqrt(x[0]**2+x[1]**2+x[2]**2)
[docs]def norm(x): n=norm2(x) return [xi/n for xi in x]
[docs]def vec(a,b): return [ai-bi for ai,bi in zip(a,b)]
[docs]def getnormal(a,b,c): v1=[ai-bi for ai,bi in zip(a,b)] v2=[ci-ai for ai,ci in zip(a,c)] return norm(crossproduct(v1,v2))
[docs]def tri3d(points): n=getnormal(points[0],points[1],points[2]) p=points[0] d=-(n[0]*p[0]+n[1]*p[1]+n[2]*p[2]) #print n,d for p in points: f=n[0]*p[0]+n[1]*p[1]+n[2]*p[2]+d assert abs(f)<1e-8 z=0 if abs(n[1])>abs(n[z]):z=1 if abs(n[2])>abs(n[z]):z=2 x=0 if x==z: x=1 y=1 if y==x or y==z: y=2 p2=[(p[x],p[y]) for p in points] t=triangulate(p2) result=[] for i in range(len(t)): pp=[] for j in range(3): p=[0,0,0] p[x]=t[i][j][0] p[y]=t[i][j][1] p[z]=-(n[x]*p[x]+n[y]*p[y]+d)/n[z] pp.append(p) result.append(pp) return result
[docs]def triangulate_old(p): tri=[] for i in range(1,len(p)-1): tri.append((p[0],p[i],p[i+1])) return tri
[docs]def femlabsurface(f,n,points): s="" x=f+"=geomcoerce('face',{" p=[y.getxyz() for y in points] # print n,":",len(p) tri=tri3d(p) for i,t in enumerate(tri): if len(tri)==1: ff=f else: ff=f+"P%d"%i x+=f+"P%d,"%i s+=femlabsurface3(ff,n,t) if len(tri)>1: x=x[:-1]+"})\n" s+=x%tuple([n]*(len(tri)+1)) return s
[docs]def write_femlab(g,filename, export0D=False, export1D=False, export2D=False, export3D=False): if not export1D and not export2D and not export3D and not export3D: export3D=True head="""\ flclear fem % COMSOL version clear vrsn vrsn.name = 'COMSOL 3.2'; vrsn.ext = ''; vrsn.major = 0; vrsn.build = 222; vrsn.rcs = '$Name: $'; vrsn.date = '$Date: 2005/09/01 18:02:30 $'; fem.version = vrsn; """ tail=""" clear appl appl.mode.class = 'ConductiveMediaDC'; appl.shape = {}; appl.gporder = {}; appl.cporder = {}; appl.sshape = 2; appl.assignsuffix = '_dc'; clear pnt pnt.V0 = {}; pnt.type = {}; pnt.Qj0 = {}; pnt.name = {}; pnt.ind = []; appl.pnt = pnt; clear edg edg.Qlj = {}; edg.name = {}; edg.ind = []; appl.edg = edg; clear bnd bnd.Vref = {}; bnd.sigmabnd = {}; bnd.V0 = {}; bnd.Jn = {}; bnd.type = {}; bnd.dbnd = {}; bnd.J0 = {}; bnd.name = {}; bnd.ind = []; appl.bnd = bnd; clear equ equ.init = {}; equ.cporder = {}; equ.T0 = {}; equ.res0 = {}; equ.gporder = {}; equ.Qj = {}; equ.sigma = {}; equ.usage = {}; equ.T = {}; equ.name = {}; equ.Je = {}; equ.sigmatensor = {}; equ.sigtype = {}; equ.alpha = {}; equ.ind = []; appl.equ = equ; fem.appl{1} = appl; fem.sdim = {'x','y','z'}; fem.border = 1; fem.units = 'SI'; % Multiphysics fem=multiphysics(fem); """ s="" objs=[] if export0D: for x in g.d0.values(): assert isinstance(x,geom.point) s+="p%d=point3(%s)\n"%(x.getn(),x.getstr()) objs.append("p%d"%x.getn()) if export1D: for x in g.d1.values(): if isinstance(x,geom.line): p=x.getpoints() s+=femlabline("l%s",x.getn(),p) elif isinstance(x,geom.circle): p=x.getpoints() assert len(p)==3 s+=femlabline("l%s",x.getn(),(p[0],p[2])) elif isinstance(x,geom.lineloop): continue else: print "Warning: unknown element ",type(x) continue objs.append("l%d"%x.getn()) if export2D or export3D: for x in g.d2.values(): if isinstance(x,geom.planesurface): p=x.getpoints() s+=femlabsurface("f%s",x.getn(),p); elif isinstance(x,geom.ruledsurface): p=x.getpoints() s+=femlabsurface("f%s",x.getn(),p); elif isinstance(x,geom.surfaceloop): continue else: print "Warning: unknown element ",type(x) continue if export2D: objs.append("f%s"%x.getn()) if export3D: for x in g.d3.values(): if isinstance(x,geom.volume): p=x.getsurfaces() s+="s%s"%x.getn()+"=geomcoerce('solid',{" for y in p: s+="f%s,"%y.getn() s=s[:-1]+"})\n" else: print "Warning: unknown element ",type(x) continue objs.append("s%s"%x.getn()) s+="clear s\ns.objs={%s};\ns.name={%s};\nfem.draw=struct('s',s);\n"%\ (conv2(objs),conv3(objs)) s= head+s+tail open(filename,"w").write(s)