[docs]defnetwork_to_comsol(network,filename=None):r""" Saves the network and geometry data from the given objects into the specified file. This exports in 2D only where throats and pores have rectangular and circular shapes, respectively. Parameters ---------- network : Network The network containing the desired data Notes ----- - The exported files contain COMSOL geometry objects, not meshes. - This class exports in 2D only. """ifop.topotools.dimensionality(network).sum()==3:raiseException("COMSOL I/O class only works for 2D networks!")filename=network.nameiffilenameisNoneelsefilenamef=open(f"{filename}.mphtxt",'w')header(file=f,Nr=network.Nt,Nc=network.Np)cn=network['throat.conns']p1=network['pore.coords'][cn[:,0]]p2=network['pore.coords'][cn[:,1]]# Compute the rotation angle of throatsdif_x=p2[:,0]-p1[:,0]dif_y=p2[:,1]-p1[:,1]# Avoid division by 0m=np.array([dif_x_i!=0fordif_x_iindif_x])r=np.zeros((len(dif_x)))r[~m]=np.infr[m]=dif_y[m]/dif_x[m]angles=np.arctan(r)r_w=network['throat.diameter']rectangles(file=f,pores1=p1,pores2=p2,alphas=angles,widths=r_w)c_c=network['pore.coords']c_r=network['pore.diameter']/2.0circles(file=f,centers=c_c,radii=c_r)f.close()
defheader(file,Nr,Nc):f=filef.write('# Geometry exported by OpenPNM'+2*'\n')f.write('# Major & minor version'+'\n')f.write('0 1'+2*'\n')f.write(str(Nc+Nr)+' '+'# number of tags'+'\n')f.write('# Tags'+'\n')forrinrange(1,Nr+1):tag='r'+str(int(r))tag=str(len(tag))+' '+tagf.write(tag+'\n')forcinrange(1,Nc+1):tag='c'+str(int(c))tag=str(len(tag))+' '+tagf.write(tag+'\n')f.write('\n'+str(Nc+Nr)+' '+'# number of types'+'\n')f.write('# Types'+'\n')foriinrange(Nc+Nr):f.write('3 obj'+'\n')f.write('\n')defrectangles(file,pores1,pores2,alphas,widths):f=filep1x=pores1[:,0]+(widths/2)*np.sin(alphas)p1y=pores1[:,1]-(widths/2)*np.cos(alphas)p2x=pores2[:,0]+(widths/2)*np.sin(alphas)p2y=pores2[:,1]-(widths/2)*np.cos(alphas)p3x=pores2[:,0]-(widths/2)*np.sin(alphas)p3y=pores2[:,1]+(widths/2)*np.cos(alphas)p4x=pores1[:,0]-(widths/2)*np.sin(alphas)p4y=pores1[:,1]+(widths/2)*np.cos(alphas)forrinrange(len(pores1)):f.write('# --------- rectangle nbr '+str(r+1)+' ---------'+2*'\n')f.write('0 0 1'+'\n')f.write('5 Geom2 # class'+'\n')f.write('2 # version'+'\n')f.write('2 # type'+'\n')f.write('1 # voidsLabeled'+'\n')f.write('1e-010 # gtol'+'\n')f.write('0.0001 # resTol'+2*'\n')f.write('4 # number of vertices'+'\n')f.write('# Vertices'+'\n')f.write('# X Y dom tol'+'\n')f.write(str(p1x[r])+' '+str(p1y[r])+' '+'-1 NAN'+'\n')f.write(str(p2x[r])+' '+str(p2y[r])+' '+'-1 NAN'+'\n')f.write(str(p3x[r])+' '+str(p3y[r])+' '+'-1 NAN'+'\n')f.write(str(p4x[r])+' '+str(p4y[r])+' '+'-1 NAN'+2*'\n')f.write('4 # number of edges'+'\n')f.write('# Edges'+'\n')f.write('# vtx1 vtx2 s1 s2 up down mfd tol'+'\n')f.write('2 1 0 1 0 1 1 NAN'+'\n')f.write('3 2 0 1 0 1 2 NAN'+'\n')f.write('4 3 0 1 0 1 3 NAN'+'\n')f.write('1 4 0 1 0 1 4 NAN'+2*'\n')f.write('4 # number of manifolds'+'\n')f.write('# Manifolds'+2*'\n')f.write('# Manifold #0'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('1 0 # degrees'+'\n')f.write('2 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')f.write(str(p2x[r])+' '+str(p2y[r])+' '+'1'+'\n')f.write(str(p1x[r])+' '+str(p1y[r])+' '+'1'+2*'\n')f.write('# Manifold #1'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('1 0 # degrees'+'\n')f.write('2 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')f.write(str(p3x[r])+' '+str(p3y[r])+' '+'1'+'\n')f.write(str(p2x[r])+' '+str(p2y[r])+' '+'1'+2*'\n')f.write('# Manifold #2'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('1 0 # degrees'+'\n')f.write('2 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')f.write(str(p4x[r])+' '+str(p4y[r])+' '+'1'+'\n')f.write(str(p3x[r])+' '+str(p3y[r])+' '+'1'+2*'\n')f.write('# Manifold #3'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('1 0 # degrees'+'\n')f.write('2 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')f.write(str(p1x[r])+' '+str(p1y[r])+' '+'1'+'\n')f.write(str(p4x[r])+' '+str(p4y[r])+' '+'1'+2*'\n')f.write('# Attributes'+'\n')f.write('0 # nof attributes'+2*'\n')defcircles(file,centers,radii):f=filep1x=centers[:,0]-radiip1y=centers[:,1]p2x=centers[:,0]p2y=centers[:,1]-radiip3x=centers[:,0]+radiip3y=centers[:,1]p4x=centers[:,0]p4y=centers[:,1]+radiiforcinrange(len(centers)):f.write('# --------- circle nbr '+str(c+1)+' ---------'+2*'\n')f.write('0 0 1'+'\n')f.write('5 Geom2 # class'+'\n')f.write('2 # version'+'\n')f.write('2 # type'+'\n')f.write('1 # voidsLabeled'+'\n')f.write('1e-010 # gtol'+'\n')f.write('0.0001 # resTol'+2*'\n')f.write('4 # number of vertices'+'\n')f.write('# Vertices'+'\n')f.write('# X Y dom tol'+'\n')# extreme left point of the circlef.write(str(p1x[c])+' '+str(p1y[c])+' '+'-1 NAN'+'\n')# extreme bottom point of the circlef.write(str(p2x[c])+' '+str(p2y[c])+' '+'-1 NAN'+'\n')# extreme right point of the circlef.write(str(p3x[c])+' '+str(p3y[c])+' '+'-1 NAN'+'\n')# extreme top point of the circlef.write(str(p4x[c])+' '+str(p4y[c])+' '+'-1 NAN'+2*'\n')f.write('4 # number of edges'+'\n')f.write('# Edges'+'\n')f.write('# vtx1 vtx2 s1 s2 up down mfd tol'+'\n')f.write('2 1 0 1 0 1 1 NAN'+'\n')f.write('3 2 0 1 0 1 2 NAN'+'\n')f.write('4 3 0 1 0 1 3 NAN'+'\n')f.write('1 4 0 1 0 1 4 NAN'+2*'\n')f.write('4 # number of manifolds'+'\n')f.write('# Manifolds'+2*'\n')# bottom left quart of the circlef.write('# Manifold #0'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('2 0 # degrees'+'\n')f.write('3 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')# extreme bottom point of the circlef.write(str(p2x[c])+' '+str(p2y[c])+' '+'1'+'\n')f.write(str(p1x[c])+' '+str(p2y[c])+' '+'0.70710678118654746'+'\n')# extreme left point of the circlef.write(str(p1x[c])+' '+str(p1y[c])+' '+'1'+2*'\n')# bottom right quart of the circlef.write('# Manifold #1'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('2 0 # degrees'+'\n')f.write('3 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')# extreme right point of the circlef.write(str(p3x[c])+' '+str(p3y[c])+' '+'1'+'\n')f.write(str(p3x[c])+' '+str(p2y[c])+' '+'0.70710678118654746'+'\n')# extreme bottom point of the circlef.write(str(p2x[c])+' '+str(p2y[c])+' '+'1'+2*'\n')# top right quart of the circlef.write('# Manifold #2'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('2 0 # degrees'+'\n')f.write('3 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')# extreme top point of the circlef.write(str(p4x[c])+' '+str(p4y[c])+' '+'1'+'\n')f.write(str(p3x[c])+' '+str(p4y[c])+' '+'0.70710678118654746'+'\n')# extreme right point of the circlef.write(str(p3x[c])+' '+str(p3y[c])+' '+'1'+2*'\n')# top left quart of the circlef.write('# Manifold #3'+'\n')f.write('11 BezierCurve # class'+'\n')f.write('0 0 # version'+'\n')f.write('2 # sdim'+'\n')f.write('0 2 1 # transformation'+'\n')f.write('2 0 # degrees'+'\n')f.write('3 # number of control points'+'\n')f.write('# control point coords and weights'+'\n')# extreme left point of the circlef.write(str(p1x[c])+' '+str(p1y[c])+' '+'1'+'\n')f.write(str(p1x[c])+' '+str(p4y[c])+' '+'0.70710678118654746'+'\n')# extreme top point of the circlef.write(str(p4x[c])+' '+str(p4y[c])+' '+'1'+2*'\n')f.write('# Attributes'+'\n')f.write('0 # nof attributes'+2*'\n')