Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #load python modules used
- import numpy as np
- import mpmath
- import sympy
- from sympy import Point3D, Line3D, Plane, Segment3D, Symbol
- from sympy.geometry import intersection, Segment3D
- import re
- from sympy.solvers import solve
- from sympy.integrals.quadrature import gauss_legendre
- import h5py
- import sys
- import math
- #CONVERT FUNCTION
- #this handles turning values returned as "a/b" to decimal format
- #this occurs for some intersection points
- #takes a value as input
- def convert(z):
- try:
- return float(z)
- except ValueError:
- num, denom = z.split('/')
- return float(num) / float(denom)
- #INTERSECTION FUNCTION
- #finds intersections between plane and line entities
- #takes a plane, line, and storage list as input
- def find_intersection(a,b,XYZ):
- #loop over the geometry entities and find intersections
- for i in range(6):
- for j in range(12):
- s=intersection(a[i],b[j])#get intersection
- #sort through the intersection data and retrieve numbers from the output string
- if s and (b[j].contains(s[0])==True):#if intersection exists and point is on edge
- d=str(s[0])
- l=len(d)
- r1=[]
- w1=[]
- if(type(s[0])==sympy.geometry.line.Segment3D):#if intersection is line segment type
- e=d[18:(l-1)]
- q=re.search('P(.*?)\)', e)
- l=len(q.group(1))
- u=q.group(1)[7:l]
- if(u not in XYZ):
- XYZ.append(u)
- w=u.split(",")
- f=re.search('(.*?)\)', e)
- g=f.group(1)
- if(g not in XYZ):
- XYZ.append(g)
- if(type(s[0])==sympy.geometry.point.Point3D):#if intersection is point type
- e=d[8:(l-1)]
- if(e not in XYZ):
- XYZ.append(e)
- return XYZ
- #FUNCTION SOLVING FOR ISOPARAMENTRIC COORDINATES
- #takes x,y,z coefficients, point coordinates, and symbols xi, eta, zeta as inputs
- def isoparametric(a,b,c,r1,xi,eta,zeta):
- Q=[] #list storage for output
- #set up a system of linear equations for x,y,z in terms of xi,eta,zeta
- #the equation is solved and the solutions are returned
- iso_point=solve((
- a[0]+a[1]*xi+a[2]*eta+a[3]*zeta+a[4]*xi*eta+a[5]*eta*zeta+a[6]*xi*zeta+a[7]*xi*eta*zeta-r1[0],
- b[0]+b[1]*xi+b[2]*eta+b[3]*zeta+b[4]*xi*eta+b[5]*eta*zeta+b[6]*xi*zeta+b[7]*xi*eta*zeta-r1[1],
- c[0]+c[1]*xi+c[2]*eta+c[3]*zeta+c[4]*xi*eta+c[5]*eta*zeta+c[6]*xi*zeta+c[7]*xi*eta*zeta-r1[2]),
- xi, eta, zeta)
- #perform tests for the output type
- #the data type will vary depending upon if there are multiple solutions or not
- test='good'
- try:
- Q.append(iso_point[0][0])
- except:
- test='bad'
- if(test=='bad'):
- Q.append(iso_point[xi])
- Q.append(iso_point[eta])
- Q.append(iso_point[zeta])
- if(test=='good'):
- #check whether each solution is real or not
- if(iso_point[0][0].is_Add ==True or
- iso_point[0][1].is_Add ==True or
- iso_point[0][2].is_Add ==True):
- #fill Q will dummy values that will get rejected
- Q[0]=10000000
- Q.append(10000000)
- Q.append(10000000)
- if(iso_point[0][0].is_real ==True and
- iso_point[0][1].is_real ==True and
- iso_point[0][2].is_real ==True):
- #check if the point is within the isoparametric bounds
- if(round(min(iso_point[0]),7)<-1 or round(max(iso_point[0]),7)>1):
- Q[0]=iso_point[1][0]
- Q.append(iso_point[1][1])
- Q.append(iso_point[1][2])
- if(round(min(iso_point[1]),7)<-1 or round(max(iso_point[1]),7)>1):
- Q[0]=iso_point[0][0]
- Q.append(iso_point[0][1])
- Q.append(iso_point[0][2])
- return Q
- #JACOBIAN FUNCTION
- #takes x,y,z coefficients, and lists of coordinates as input
- def J1(a,b,c,x,y,z):
- #partial derivatives
- dx_1=a[1]+(a[4]*y)+(a[6]*z)+(a[7]*y*z)
- dx_2=a[2]+(a[4]*x)+(a[5]*z)+(a[7]*x*z)
- dx_3=a[3]+(a[5]*y)+(a[6]*x)+(a[7]*x*y)
- dy_1=b[1]+(b[4]*y)+(b[6]*z)+(b[7]*y*z)
- dy_2=b[2]+(b[4]*x)+(b[5]*z)+(b[7]*x*z)
- dy_3=b[3]+(b[5]*y)+(b[6]*x)+(b[7]*x*y)
- dz_1=c[1]+(c[4]*y)+(c[6]*z)+(c[7]*y*z)
- dz_2=c[2]+(c[4]*x)+(c[5]*z)+(c[7]*x*z)
- dz_3=c[3]+(c[5]*y)+(c[6]*x)+(c[7]*x*y)
- #jacobian matrix
- B=np.zeros([3,3])
- B[0,:]=[dx_1,dx_2,dx_3]
- B[1,:]=[dy_1,dy_2,dy_3]
- B[2,:]=[dz_1,dz_2,dz_3]
- j=np.linalg.det(B)
- return abs(j)
- #FUNCTION FOR FINDING INTEGRAL VALUES USING SHAPE FUNCTIONS
- #takes x,y,z coefficients, point coordinates, and point values as input
- def shape(a,b,c,x,y,z,u):
- #matrix of coefficients for xi,et,zeta terms in shape functions
- A=np.ones([NEN,3])
- A[0,:]=[-1,-1,-1]
- A[1,:]=[1,-1,-1]
- A[2,:]=[1,1,-1]
- A[3,:]=[-1,1,-1]
- A[4,:]=[-1,-1,1]
- A[5,:]=[1,-1,1]
- A[6,:]=[1,1,1]
- A[7,:]=[-1,1,1]
- #get jacobian
- j=J1(a,b,c,x,y,z)
- #sum contributions from each shape function
- #called as part of gauss quadrature
- NSUM=0
- for i in range(NEN):
- NSUM=NSUM+((abs(j)*u[i]*(1+(x*A[i,0]))*(1+(y*A[i,1]))*(1+(z*A[i,2])))/8)
- return NSUM
- #FUNCTION FOR FINDING POINT VALUES USING SHAPE FUNCTIONS
- #takes x,y,z coefficients, point coordinates, and point values as input
- def shapeVal(a,b,c,x,y,z,u):
- A=np.ones([NEN,3])
- A[0,:]=[-1,-1,-1]
- A[1,:]=[1,-1,-1]
- A[2,:]=[1,1,-1]
- A[3,:]=[-1,1,-1]
- A[4,:]=[-1,-1,1]
- A[5,:]=[1,-1,1]
- A[6,:]=[1,1,1]
- A[7,:]=[-1,1,1]
- #sum contributions from each shape function
- NSUM=0
- for i in range(NEN):
- NSUM=NSUM+(u[i]*(1+(x*A[i,0]))*(1+(y*A[i,1]))*(1+(z*A[i,2])))/8
- return NSUM
- #FUNCTION FOR TET SHAPE FUNCTION INTEGRATION
- #takes array of x,y,z coordinates and values, point coordinates as input
- def tet_iso(T,x,y,z):
- a=np.zeros([4,3]) #isoparametric coefficients for tets
- J=np.zeros([3,3]) #jacobian matrix
- p=[]
- for i in range(3):
- a[0,i]=T[0,i]
- a[1,i]=T[1,i]-T[0,i]
- a[2,i]=T[2,i]-T[0,i]
- a[3,i]=T[3,i]-T[0,i]
- for i in range(3):
- for j in range(3):
- J[i,j]=a[j+1,i]
- jacobian=np.linalg.det(J)
- U=abs(jacobian)*T[0,3]+(x*(T[1,3]-T[0,3]))+(y*(T[2,3]-T[0,3]))+(z*(T[3,3]-T[0,3]))
- return U
- #FUNCTION FOR HEX SHAPE FUNCTION INTEGRATION
- #takes array of x,y,z coordinates and values,x,y,z coefficients, and point coordinates as input
- def hex_iso(T,a,b,c,x,y,z):
- A=np.ones([NEN,3])
- A[0,:]=[-1,-1,-1]
- A[1,:]=[1,-1,-1]
- A[2,:]=[1,1,-1]
- A[3,:]=[-1,1,-1]
- A[4,:]=[-1,-1,1]
- A[5,:]=[1,-1,1]
- A[6,:]=[1,1,1]
- A[7,:]=[-1,1,1]
- #get jacobian
- j=J1(a,b,c,x,y,z)
- NSUM=0
- for i in range(NEN):
- NSUM=NSUM+((abs(j)*T[i,3]*(1+(x*A[i,0]))*(1+(y*A[i,1]))*(1+(z*A[i,2])))/8)
- return NSUM
- #GAUSS QUADRATURE FUNCTION
- #takes takes array of x,y,z coordinates and values, quadrature points and weights,
- #and sets of x,y,z coefficients as input
- def Gquad(T,xg,wg,a1,b1,c1,a,b,c):
- sumg=0
- L=len(T[:,0])
- for i in range(3):
- for j in range(3):
- for k in range(3):
- if(L==4):
- sumg=sumg+(tet_iso(T,xg[i],xg[j],xg[k])*wg[i]*wg[j]*wg[k]*J1(a,b,c,xg[i],xg[j],xg[k]))
- if(L==8):
- sumg=sumg+(hex_iso(T,a1,b1,c1,xg[i],xg[j],xg[k])*wg[i]*wg[j]*wg[k]*J1(a,b,c,xg[i],xg[j],xg[k]))
- return sumg
- #FUNCTION FOR FINDING HEX VOLUME
- #takes x,y,z coordinate lists, and NEN as input
- def hexVol(x,y,z,NEN):
- #fill h with node coordinates
- h=np.zeros([NEN,3])
- for i in range(NEN):
- h[i,0]=x[i]
- h[i,1]=y[i]
- h[i,2]=z[i]
- A=np.ones([4,4])
- B=np.ones([4,4])
- C=np.ones([4,4])
- D=np.ones([4,4])
- E=np.ones([4,4])
- #fill matrices A,B,C,D,E using handles
- #matrices define the 5 tets needed to get hex volume
- for i in range(3):
- A[0,i]=h[0,i]
- A[1,i]=h[1,i]
- A[2,i]=h[3,i]
- A[3,i]=h[4,i]
- B[0,i]=h[1,i]
- B[1,i]=h[2,i]
- B[2,i]=h[3,i]
- B[3,i]=h[6,i]
- C[0,i]=h[1,i]
- C[1,i]=h[4,i]
- C[2,i]=h[5,i]
- C[3,i]=h[6,i]
- D[0,i]=h[3,i]
- D[1,i]=h[4,i]
- D[2,i]=h[6,i]
- D[3,i]=h[7,i]
- E[0,i]=h[1,i]
- E[1,i]=h[3,i]
- E[2,i]=h[4,i]
- E[3,i]=h[6,i]
- VA=abs(np.linalg.det(A))
- VB=abs(np.linalg.det(B))
- VC=abs(np.linalg.det(C))
- VD=abs(np.linalg.det(D))
- VE=abs(np.linalg.det(E))
- V=(VA+VB+VC+VD+VE)/6
- return V
- #FUNCTION FOR CHECKING IF A POINT IS INSIDE A HEX VOLUME
- #takes x,y,z coordinate lists,NEN, and point coordinates as input
- def NewHexVol(x,y,z,NEN,p):
- #fill h with node coordinates
- h=np.zeros([NEN,3])
- for i in range(NEN):
- h[i,0]=x[i]
- h[i,1]=y[i]
- h[i,2]=z[i]
- A=np.ones([4,4])
- VA=0.0
- #find volumes of 12 tets cre4ated using the test point
- #A is iteratively set up as each of the 12 required tets
- for j in range(12):
- for i in range(3):
- if(j==0):
- A[0,i]=h[0,i]
- A[1,i]=h[1,i]
- A[2,i]=h[2,i]
- A[3,i]=p[i]
- if(j==1):
- A[0,i]=h[0,i]
- A[1,i]=h[3,i]
- A[2,i]=h[2,i]
- A[3,i]=p[i]
- if(j==2):
- A[0,i]=h[0,i]
- A[1,i]=h[3,i]
- A[2,i]=h[4,i]
- A[3,i]=p[i]
- if(j==3):
- A[0,i]=h[0,i]
- A[1,i]=h[1,i]
- A[2,i]=h[4,i]
- A[3,i]=p[i]
- if(j==4):
- A[0,i]=h[1,i]
- A[1,i]=h[2,i]
- A[2,i]=h[5,i]
- A[3,i]=p[i]
- if(j==5):
- A[0,i]=h[1,i]
- A[1,i]=h[4,i]
- A[2,i]=h[5,i]
- A[3,i]=p[i]
- if(j==6):
- A[0,i]=h[2,i]
- A[1,i]=h[5,i]
- A[2,i]=h[6,i]
- A[3,i]=p[i]
- if(j==7):
- A[0,i]=h[2,i]
- A[1,i]=h[3,i]
- A[2,i]=h[7,i]
- A[3,i]=p[i]
- if(j==8):
- A[0,i]=h[2,i]
- A[1,i]=h[7,i]
- A[2,i]=h[6,i]
- A[3,i]=p[i]
- if(j==9):
- A[0,i]=h[5,i]
- A[1,i]=h[6,i]
- A[2,i]=h[4,i]
- A[3,i]=p[i]
- if(j==10):
- A[0,i]=h[4,i]
- A[1,i]=h[6,i]
- A[2,i]=h[7,i]
- A[3,i]=p[i]
- if(j==11):
- A[0,i]=h[4,i]
- A[1,i]=h[3,i]
- A[2,i]=h[7,i]
- A[3,i]=p[i]
- #sum volumes
- VA=VA+abs(np.linalg.det(A))
- V=VA/6
- return V
- #ELEMENT FUNCTION - perform operations on each PROTEUS element
- def element(ee,nEl,MCNP_el_val,M,m,xyz,NEN,dim,vDat,XMIN,XMAX,YMIN,YMAX,ZMIN,ZMAX,center,max_dim):
- #storage lists
- points=[]
- x=[]
- y=[]
- z=[]
- val=[]
- #load the PROTEUS node coordinates and values
- #rounding is due to the python float data type appending digits
- #the source file provides 7 decimals
- for n in range(NEN):#loop over nodes
- x.append(round((xyz[n+(NEN*ee*dim)]),7))
- y.append(round((xyz[n+(NEN)+(NEN*ee*dim)]),7))
- z.append(round((xyz[n+(NEN*2)+(NEN*ee*dim)]),7))
- val.append(round((vDat[3,n+(NEN*ee)]),7))
- #perform checks to see if PROTEUS elements are near the target MCNP element
- neighbor=False
- #limiting search to a single z slice of 1 pin
- if(round(z[0],7)>=0.05 and round(z[0],7)<=0.15):
- #check the distance of each node from the MCNP element center
- for i in range(NEN):
- d=(((center[0]-x[i])**2)+((center[1]-y[i])**2)+((center[2]-z[i])**2))**0.5
- if(d<=((2**.5)*max_dim/2)):
- neighbor=True
- break
- #only run for neighboring nodes
- if(neighbor==True):
- A=np.ones([8,8])
- A[0,:]=[1,-1,-1,-1,1,1,1,-1]
- A[1,:]=[1,1,-1,-1,-1,1,-1,1]
- A[2,:]=[1,1,1,-1,1,-1,-1,-1]
- A[3,:]=[1,-1,1,-1,-1,-1,1,1]
- A[4,:]=[1,-1,-1,1,1,-1,-1,1]
- A[5,:]=[1,1,-1,1,-1,-1,1,-1]
- A[7,:]=[1,-1,1,1,-1,1,-1,-1]
- A_inv=np.linalg.matrix_power(A,-1)
- #coefficients for isoparametric coordinate functions
- a=np.matmul(A_inv,x)
- b=np.matmul(A_inv,y)
- c=np.matmul(A_inv,z)
- #array to store intersection points - assume maximum of 10 points
- N=np.zeros([10,3])
- pnts=0
- V=hexVol(x,y,z,NEN) #full PROTEUS element volume
- inside=0
- for i in range(NEN):
- #check if any PROTEUS nodes are inside the MCNP element
- if(x[i]>=XMIN and x[i]<=XMAX and y[i]>=YMIN and y[i]<=YMAX and z[i]>=ZMIN and z[i]<=ZMAX):
- rr1=[x[i],y[i],z[i]]
- Q=isoparametric(a,b,c,rr1,xi,eta,zeta)
- qw.write(str(x[i])+','+str(y[i])+','+str(z[i])+'\n')
- N[pnts,0]=round(Q[0],7)
- N[pnts,1]=round(Q[1],7)
- N[pnts,2]=round(Q[2],7)
- pnts=pnts+1 #counter for number of intersection points
- inside=inside+1 #count the number of PROTEUS nodes inside the MCNP element
- r1=[xm[i],ym[i],zm[i]] #MCNP node coordinates
- V2=NewHexVol(x,y,z,NEN,r1)
- #check if any MCNP nodes are inside the PROTEUS element
- if(V2<=V):
- Q=isoparametric(a,b,c,r1,xi,eta,zeta)
- N[pnts,0]=round(Q[0],7)
- N[pnts,1]=round(Q[1],7)
- N[pnts,2]=round(Q[2],7)
- pnts=pnts+1
- #create 3D point entities for finding intersections
- for i in range(len(x)):
- points.append(Point3D(x[i],y[i],z[i]))
- if(inside!=NEN): #only execute the rest if all PROTEUS nodes are not inside MCNP element
- P=[] #PROTEUS faces
- p=[] #PROTEUS edges
- #create lists of planes and edges for each element
- P.append(Plane(points[0],points[1],points[2]))
- P.append(Plane(points[0],points[1],points[4]))
- P.append(Plane(points[0],points[3],points[4]))
- P.append(Plane(points[5],points[6],points[2]))
- P.append(Plane(points[5],points[6],points[7]))
- P.append(Plane(points[2],points[3],points[6]))
- p.append(Segment3D(points[0],points[1]))
- p.append(Segment3D(points[1],points[2]))
- p.append(Segment3D(points[2],points[3]))
- p.append(Segment3D(points[3],points[0]))
- p.append(Segment3D(points[4],points[5]))
- p.append(Segment3D(points[5],points[6]))
- p.append(Segment3D(points[6],points[7]))
- p.append(Segment3D(points[7],points[4]))
- p.append(Segment3D(points[1],points[5]))
- p.append(Segment3D(points[2],points[6]))
- p.append(Segment3D(points[3],points[7]))
- p.append(Segment3D(points[0],points[4]))
- XYZ=[] #storage for intersection coordinates
- #check for PROTEUS edges intersecting MCNP planes
- #check for MCNP edges intersecting PROTEUS planes
- find_intersection(M,p,XYZ)
- find_intersection(P,m,XYZ)
- l=len(XYZ)
- #iterate over all possible intersections
- for i in range(l):
- r1=[]
- Q=[]
- #convert intersections to numeric format
- r=XYZ[i].split(",")
- for k in range(3):
- r1.append(convert(r[k]))
- Q=isoparametric(a,b,c,r1,xi,eta,zeta)
- #check is Q is within PROTEUS element limits
- if(round(max(Q),7)<=1 and round(min(Q),7)>=-1
- and r1[0]>=XMIN and r1[0]<=XMAX and r1[1]>=YMIN
- and r1[1]<=YMAX and r1[2]>=ZMIN and r1[2]<=ZMAX):
- qw.write(str(r1[0])+','+str(r1[1])+','+str(r1[2])+'\n')
- #store valid points in N
- N[pnts,0]=round((Q[0]),7)
- N[pnts,1]=round((Q[1]),7)
- N[pnts,2]=round((Q[2]),7)
- pnts=pnts+1
- #at this point all the intersections are found
- if(pnts>3):
- #reorder the intersection points
- #nodes are ordered in a counterclockwise fashion in each z plane
- k=pnts-1
- while (k>0):
- l=0
- for j in range(k):
- if((N[j,2]>N[j+1,2]) or (N[j,2] == N[j+1,2] and N[j,0] > N[j+1,0]) or
- (N[j,2] == N[j+1,2] and N[j,0] == N[j+1,0] and N[j,1] > N[j+1,1])):
- for mm in range(3):
- tmp=N[j,mm]
- N[j,mm]=N[j+1,mm]
- N[j+1,mm]=tmp
- l=j
- k=l
- int_vals=np.zeros([pnts])
- #calculate value for each intersection point after reordering
- for i in range(pnts):
- int_vals[i]=shapeVal(a,b,c,N[i,0],N[i,1],N[i,2],val)
- #assign nodes to each piece of the intersection
- #assign nodal values
- #this section assigns the intersection nodes to matrices
- #procedure varies by number of nodes
- #some shapes are broken into simpler shapes
- #integration is then done over the intersection regions
- #the intersection is transformed to its own isoparametric coordinates
- #jacobians from the original and new mapping are used in the calculations
- #hex - not split
- if(pnts==8):
- #lists storing x,y,z values
- ax=[]
- ay=[]
- az=[]
- Nh=np.zeros([8,4])
- #fill Nh and do slight reordering
- #order is modified for matrix solving
- for i in range(3):
- for j in range(8):
- Nh[j,i]=N[j,i]
- Nh[1,i]=N[3,i]
- Nh[3,i]=N[1,i]
- Nh[5,i]=N[7,i]
- Nh[7,i]=N[5,i]
- for i in range(8):
- Nh[i,3]=int_vals[i]
- ax.append(Nh[i,0])
- ay.append(Nh[i,1])
- az.append(Nh[i,2])
- Nh[1,3]=int_vals[3]
- Nh[3,3]=int_vals[1]
- Nh[5,3]=int_vals[7]
- #get isoparametric coefficients
- a1=np.matmul(A_inv,ax)
- b1=np.matmul(A_inv,ay)
- c1=np.matmul(A_inv,az)
- MCNP_el_val=MCNP_el_val+(Gquad(Nh,xg,wg,a1,b1,c1,a,b,c))
- #tet - not split
- if(pnts==4):
- Nt1=np.zeros([4,4])
- for i in range(3):
- Nt1[0,i]=N[0,i]
- Nt1[1,i]=N[1,i]
- Nt1[2,i]=N[2,i]
- Nt1[3,i]=N[3,i]
- Nt1[0,3]=int_vals[0]
- Nt1[1,3]=int_vals[1]
- Nt1[2,3]=int_vals[2]
- Nt1[3,3]=int_vals[3]
- print(Nt1)
- MCNP_el_val=MCNP_el_val+(Gquad(Nt1,xg,wg,0,0,0,a,b,c))
- #pentahedral - split into 1 hex and 3 tets
- if(pnts==10):
- ax=[]
- ay=[]
- az=[]
- Nh=np.zeros([8,4])
- Nt1=np.zeros([4,4])
- Nt2=np.zeros([4,4])
- Nt3=np.zeros([4,4])
- for i in range(3):
- Nh[0,i]=N[0,i]
- Nh[1,i]=N[4,i]
- Nh[2,i]=N[2,i]
- Nh[3,i]=N[1,i]
- Nh[4,i]=N[5,i]
- Nh[5,i]=N[9,i]
- Nh[6,i]=N[7,i]
- Nh[7,i]=N[6,i]
- Nt1[0,i]=N[7,i]
- Nt1[1,i]=N[8,i]
- Nt1[2,i]=N[9,i]
- Nt1[3,i]=N[2,i]
- Nt2[0,i]=N[8,i]
- Nt2[1,i]=N[9,i]
- Nt2[2,i]=N[2,i]
- Nt2[3,i]=N[3,i]
- Nt3[0,i]=N[9,i]
- Nt3[1,i]=N[2,i]
- Nt3[2,i]=N[3,i]
- Nt3[3,i]=N[4,i]
- for i in range(8):
- ax.append(Nh[i,0])
- ay.append(Nh[i,1])
- az.append(Nh[i,2])
- Nh[0,3]=int_vals[0]
- Nh[1,3]=int_vals[4]
- Nh[2,3]=int_vals[2]
- Nh[3,3]=int_vals[1]
- Nh[4,3]=int_vals[5]
- Nh[5,3]=int_vals[9]
- Nh[6,3]=int_vals[7]
- Nh[7,3]=int_vals[6]
- a1=np.matmul(A_inv,ax)
- b1=np.matmul(A_inv,ay)
- c1=np.matmul(A_inv,az)
- Nt1[0,3]=int_vals[7]
- Nt1[1,3]=int_vals[8]
- Nt1[2,3]=int_vals[9]
- Nt1[3,3]=int_vals[2]
- Nt2[0,3]=int_vals[8]
- Nt2[1,3]=int_vals[9]
- Nt2[2,3]=int_vals[2]
- Nt2[3,3]=int_vals[3]
- Nt3[0,3]=int_vals[9]
- Nt3[1,3]=int_vals[2]
- Nt3[2,3]=int_vals[3]
- Nt3[3,3]=int_vals[4]
- MCNP_el_val=MCNP_el_val+(Gquad(Nt1,xg,wg,0,0,0,a,b,c)+
- Gquad(Nt2,xg,wg,0,0,0)+Gquad(Nt3,xg,wg,0,0,0,a,b,c)+
- Gquad(Nh,xg,wg,a1,b1,c1,a,b,c))
- #prism - split into tets
- if(pnts==6):
- Nt1=np.zeros([4,4])
- Nt2=np.zeros([4,4])
- Nt3=np.zeros([4,4])
- for i in range(3):
- Nt1[0,i]=N[3,i]
- Nt1[1,i]=N[4,i]
- Nt1[2,i]=N[5,i]
- Nt1[3,i]=N[1,i]
- Nt2[0,i]=N[5,i]
- Nt2[1,i]=N[3,i]
- Nt2[2,i]=N[1,i]
- Nt2[3,i]=N[2,i]
- Nt3[0,i]=N[3,i]
- Nt3[1,i]=N[1,i]
- Nt3[2,i]=N[2,i]
- Nt3[3,i]=N[0,i]
- Nt1[0,3]=int_vals[3]
- Nt1[1,3]=int_vals[4]
- Nt1[2,3]=int_vals[5]
- Nt1[3,3]=int_vals[1]
- Nt2[0,3]=int_vals[5]
- Nt2[1,3]=int_vals[3]
- Nt2[2,3]=int_vals[1]
- Nt2[3,3]=int_vals[2]
- Nt3[0,3]=int_vals[3]
- Nt3[1,3]=int_vals[1]
- Nt3[2,3]=int_vals[2]
- Nt3[3,3]=int_vals[0]
- MCNP_el_val=MCNP_el_val+(Gquad(Nt1,xg,wg,0,0,0,a,b,c)+
- Gquad(Nt2,xg,wg,0,0,0,a,b,c)+Gquad(Nt3,xg,wg,0,0,0,a,b,c))
- #this part of the code is called is all PROTEUS nodes are inside the MCNP element
- if(inside==NEN):
- sumg=0.0 #initialize summation
- #perform gauss quadrature
- for i in range(3):
- for j in range(3):
- for k in range(3):
- sumg=sumg+(shape(a,b,c,xg[i],xg[j],xg[k],val)*wg[i]*wg[j]*wg[k])
- MCNP_el_val=MCNP_el_val+sumg # add to MCNP element total
- return MCNP_el_val
- #MAIN FUNCTION
- #symbols for equation solving
- xi=Symbol('xi')
- eta=Symbol('eta')
- zeta=Symbol('zeta')
- #get points and weights for gauss quadrature
- xg, wg = gauss_legendre(3, 10)
- #load PROTEUS output file
- f=h5py.File(r'C:\Users\Peter\Documents\FEP\Project\3D Mesh\RCF_2x2.h5')
- #get the hdf5 keys
- tier1=list(f.keys())
- con=f[('CONTROL')]
- blocks=con[0] #number of material regions
- dim=con[1] #dimension
- #open output files
- qw=open('intersections.csv','w')
- windows=open('windows.csv','w')
- #MCNP mesh parameters
- #outer limits and number of divisions
- iints=2
- jints=2
- kints=1
- Xhigh=0.9
- Yhigh=0.9
- Zhigh=.1
- Xlow=-0.9
- Ylow=-0.9
- Zlow=0
- del_x=(Xhigh-Xlow)/iints
- del_y=(Yhigh-Ylow)/jints
- del_z=(Zhigh-Zlow)/kints
- #loop iterating over the MCNPm elements
- for mk in range(kints):
- for mj in range(jints):
- for mi in range(iints):
- MCNP_el_val=0.0 #initialize the value for the element
- #MCNP element limits
- XMIN=Xlow+(mi*del_x)
- YMIN=Ylow+(mj*del_y)
- ZMIN=Zlow+(mk*del_y)
- XMAX=XMIN+del_x
- YMAX=YMIN+del_y
- ZMAX=ZMIN+del_z
- #find the element center
- center=[]
- center.append(XMIN+((XMAX-XMIN)/2))
- center.append(YMIN+((YMAX-YMIN)/2))
- center.append(ZMIN+((ZMAX-ZMIN)/2))
- #find the maximim distance to a face of the element
- Dist=[]
- Dist.append(XMAX-XMIN)
- Dist.append(YMAX-YMIN)
- Dist.append(ZMAX-ZMIN)
- max_dim=max(Dist)
- #MCNP element node coordinates
- xm=[XMIN,XMAX,XMAX,XMIN,XMIN,XMAX,XMAX,XMIN]
- ym=[YMIN,YMIN,YMAX,YMAX,YMIN,YMIN,YMAX,YMAX]
- zm=[ZMIN,ZMIN,ZMIN,ZMIN,ZMAX,ZMAX,ZMAX,ZMAX]
- #setup SymPy style points, edges, and planes for finding intersections
- #create Point3D entities using MCNP node coordinates
- #the Point3D entities are used for constructing planes and edges
- pointsM=[]
- for i in range(8):
- pointsM.append(Point3D(xm[i],ym[i],zm[i]))
- M=[] #MCNP faces
- m=[] #MCNP edges
- #fill lists with planes and edges
- M.append(Plane(pointsM[0],pointsM[1],pointsM[2]))
- M.append(Plane(pointsM[0],pointsM[1],pointsM[4]))
- M.append(Plane(pointsM[0],pointsM[3],pointsM[4]))
- M.append(Plane(pointsM[5],pointsM[6],pointsM[2]))
- M.append(Plane(pointsM[5],pointsM[6],pointsM[7]))
- M.append(Plane(pointsM[2],pointsM[3],pointsM[6]))
- m.append(Segment3D(pointsM[0],pointsM[1]))
- m.append(Segment3D(pointsM[1],pointsM[2]))
- m.append(Segment3D(pointsM[2],pointsM[3]))
- m.append(Segment3D(pointsM[3],pointsM[0]))
- m.append(Segment3D(pointsM[4],pointsM[5]))
- m.append(Segment3D(pointsM[5],pointsM[6]))
- m.append(Segment3D(pointsM[6],pointsM[7]))
- m.append(Segment3D(pointsM[7],pointsM[4]))
- m.append(Segment3D(pointsM[1],pointsM[5]))
- m.append(Segment3D(pointsM[2],pointsM[6]))
- m.append(Segment3D(pointsM[3],pointsM[7]))
- m.append(Segment3D(pointsM[0],pointsM[4]))
- total=0 #initialize contributions from PROTEUS elements
- #loop over blocks
- for bl in range(blocks):
- dset=f[tier1[bl]]
- subD=list(dset)
- info=dset[(subD[2])]
- vDat=dset[(subD[3])] #output data
- xyz=dset[(subD[4])] #node coordinates
- NEN=info[1] #nodes per element
- nEl=info[0] #elements per block
- #loop over elements
- for ee in range(nEl):
- #call element function to get contribution from each element
- output=element(ee,nEl,MCNP_el_val,M,m,xyz,NEN,dim,vDat,XMIN,XMAX,YMIN,YMAX,ZMIN,ZMAX,center,max_dim)
- total=total+output #add contributions to the total
- print('total: '+str(total))
- #write output to file once all element contributions from all blocks are summed
- windows.write(str(total)+',\n')
- #move on to next MCNP element
- qw.close()
- windows.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement