Exemple #1
0
    def Plot_Single(self, NumPts=10):
        """
        plots CFEM solution to BVP (red) with analytic MMS solution (blue)
        """
        plt.figure(1)
        # xplot = linspace(self.bounds[0], self.bounds[1], 100)
        # plt.plot(xplot, self.u(xplot), linewidth = 2, color = 'blue')

        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            xpp = linspace(xL, xR, NumPts)
            xww = (xpp-xL)/dx - 1.0
            ypp = zeros(NumPts)
            for j in range(0, NumPts):
                psi, dpsi = shape(xww[j], self.order[el])
                uhval = 0.0
                for k in range(0, self.order[el]):
                    mynum = self.nod[el, k]
                    uhval += self.soln[mynum]*psi[k]
                ypp[j] = uhval

            plt.plot(xpp,ypp, ".-",linewidth=1, color = 'red')
        
        plt.xlabel('Space')
        plt.grid(True)
        plt.show()
Exemple #2
0
 def LocalError(self, x):
     """
     computes the local error at some given point, x
     """
     # get element number based on position, x
     el = 0
     a = self.hel
     while a < self.bounds[1]:
         if x < a:
             break
         else:
             el += 1
         a += self.hel
     if el > self.nels-1:
         print("\n\n  in get_CellNum\n")
         print("  el for mat map in x is greater than the problem domain, this is a problem\n\n")
         sys.exit()
     # get left and right node position of element, el
     xL = self.xnod[self.nod[el, 0]]
     xR = self.xnod[self.nod[el, self.order[el]-1]]
     dx = (xR - xL)/2.0
     # evaluation reference function at x in real element
     uval = self.u(x)
     # map x to reference element
     xww = (x-xL)/dx - 1.0
     psi, dpsi = shape(xww, self.order[el])
     uhval = 0.0
     for k in range(0, self.order[el]):
         mynum = self.nod[el, k]
         uhval += self.soln[mynum]*psi[k]
     # get error at middle of given cell
     # print("  -> Computing Local Error at x={0:.4e}".format(x))
     # print("      uval, uhval = {0:.4e}, {1:.4e}".format(uval, uhval))
     self.loc_err = abs(uval - uhval)
Exemple #3
0
 def LinfError(self):
     """
     computes the L_infty error from an MMS type BVP problem
     """
     nw, xw, w = QP(self.maxord)
     self.linf_ErrVal = 0.0
     self.linf_Loc = None
     ## set mesh parameters to spatial grid
     for el in range(0, self.nels):  # for each element in all elements
         xL = self.xnod[self.nod[el, 0]]
         xR = self.xnod[self.nod[el, self.order[el]-1]]
         dx = (xR - xL)/2.0
         for l in range(0, nw):
             x = xL + (1.0 + xw[l])*dx
             psi, dpsi = shape(xw[l], self.order[el])
             uval = self.u(x)
             uhval = 0.0
             for k in range(0, self.order[el]):
                 mynum = self.nod[el, k]
                 uhval += self.soln[mynum]*psi[k]
             if abs(uval-uhval) > self.linf_ErrVal:
                 self.linf_ErrVal = abs(uval-uhval)
                 self.linf_Loc = x
     
     if self.linf_Loc == None:
         print("Max error not found! That doesn't make sense...")
         sys.exit()
Exemple #4
0
    def L2Error(self):
        """
        computes the L2 error from an MMS type BVP problem
        """
        nw, xw, w = QP(self.maxord)
        self.l2Err = 0.0
        self.h1Err = 0.0
        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            for l in range(0, nw):
                x = xL + (1.0 + xw[l])*dx
                psi, dpsi = shape(xw[l], self.order[el])
                uval = self.u(x)
                duval = self.up(x)
                uhval = 0.0
                duhval = 0.0
                for k in range(0, self.order[el]):
                    mynum = self.nod[el, k]
                    uhval += self.soln[mynum]*psi[k]
                    duhval += self.soln[mynum]*dpsi[k]/dx
                
                # complete integration over element
                self.l2Err += (uval-uhval)**2 *w[l]*dx
                self.h1Err += (duval-duhval)**2 *w[l]*dx

        self.l2Err = sqrt(self.l2Err)
        self.h1Err = sqrt(self.l2Err + self.h1Err)
Exemple #5
0
    def Plot(self, NumPts=10, string="CFEM"):
        """
        plots CFEM solution to BVP (red) with analytic MMS solution (blue)
        """
        plt.figure(1)
        # xplot = linspace(self.bounds[0], self.bounds[1], 100)
        # plt.plot(xplot, self.u(xplot), linewidth = 2, color = 'blue')

        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            xpp = linspace(xL, xR, NumPts)
            xww = (xpp-xL)/dx - 1.0
            ypp = zeros(NumPts)
            for j in range(0, NumPts):
                psi, dpsi = shape(xww[j], self.order[el])
                uhval = 0.0
                for k in range(0, self.order[el]):
                    mynum = self.nod[el, k]
                    uhval += self.soln[mynum]*psi[k]
                ypp[j] = uhval

            # if string == "DFEM":    
            #     plt.plot(xpp,ypp, ".-",linewidth=1, color = 'blue')
            # else:
            #     plt.plot(xpp,ypp, ".-",linewidth=1, color = 'red')
            if self.nels == 16:
                plt.plot(xpp, ypp, ".-", linewidth=1, color='red')
            elif self.nels == 32:
                plt.plot(xpp,ypp, ".-",linewidth=1, color = 'blue')
            elif self.nels == 64:
                plt.plot(xpp,ypp, ".-",linewidth=1, color = 'green')
        
        # plt.title("Exact solution (blue) and BVP {0} solution (red)".format(string))
        plt.xlabel('Space')
        plt.grid(True)
        # if string == "DFEM":
            # plt.title("DFEM (blue) and CFEM (red)")
        #     # plt.title("CFEM (red)")
        if self.nels == 64:
            plt.title("#Elem = 16 (red) and #Elem = 64 (green)")
            plt.show()
Exemple #6
0
    def Plot_Both(self, NumPts=10, string="CFEM"):
        """
        plots CFEM solution to BVP (red) with analytic MMS solution (blue)
        """
        plt.figure(1)
        if self.selection != 4 and string == "DFEM":
            xplot = linspace(self.bounds[0], self.bounds[1], 300)
            ref = zeros(len(xplot))
            for i,x in enumerate(xplot):
                ref[i] = self.u(x)
            plt.plot(xplot, ref, linewidth = 2, color = 'green')

        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            xpp = linspace(xL, xR, NumPts)
            xww = (xpp-xL)/dx - 1.0
            ypp = zeros(NumPts)
            for j in range(0, NumPts):
                psi, dpsi = shape(xww[j], self.order[el])
                uhval = 0.0
                for k in range(0, self.order[el]):
                    mynum = self.nod[el, k]
                    uhval += self.soln[mynum]*psi[k]
                ypp[j] = uhval

            if string == "DFEM":    
                plt.plot(xpp,ypp, ".-",linewidth=1, color = 'blue')
            else:
                plt.plot(xpp,ypp, ".-",linewidth=1, color = 'red')
        
        # plt.title("Exact solution (blue) and BVP {0} solution (red)".format(string))
        plt.xlabel('Space')
        plt.grid(True)
        if string == "DFEM":
            plt.title("DFEM (blue) and CFEM (red)")
            plt.show()
Exemple #7
0
    def DFEM_1D(self):
        """
        Solves a two-point BVP using Galerkin finite elements
        - automatically switches between continuous or discontinuous 
          based on mesh it has access to
        """
        nw, xw, w = QP(self.maxord)

        ## set up matrix and rhs of linear system
        self.stiff = zeros((self.nnodes, self.nnodes))
        self.mass = zeros((self.nnodes, self.nnodes))
        self.curr = zeros((self.nnodes, self.nnodes)) # "current" matrix used in DFEM (default to zeros for CFEM)
        self.rhsf = zeros( self.nnodes )
        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            # compute element stiffness matrix and rhs (load) vector
            k = zeros((self.order[el], self.order[el]))  # element stiffness matrix
            m = zeros((self.order[el], self.order[el]))  # element mass matrix
            f = zeros(self.order[el])     # element load vector

            for l in range(0, nw):
                # x runs in true element, xw runs in reference element
                x = xL + (1.0 + xw[l])*dx
                # calculations on ref element
                psi, dpsi = shape(xw[l], self.order[el])
                Dval = self.D(x)
                SigAbs = self.SigA(x)
                fval = self.f(x)
                f += fval * psi * w[l]*dx
                k += Dval*outer(dpsi, dpsi)/dx/dx * w[l]*dx
                m += SigAbs*outer(psi, psi) * w[l]*dx

            # # uncomment to see the local (stiffness+mass) matrix and local load vector
            # print(k)
            # print(m)
            # print(f)
            # sys.exit()

            # neutron current, J, treatments for DFEM
            # current set up, only valid for linear FEs 
            #  - can make higher order FEs by generalizing 
            if el == 0:
                self.Curr_iplus(el)
            elif el == self.nels-1:
                self.Curr_iminus(el)
            else:
                self.Curr_iminus(el)
                self.Curr_iplus(el)

            for idx in range(0, self.order[el]):
                self.rhsf[self.nod[el, idx]] += f[idx]
                for idy in range(0, self.order[el]):
                    self.stiff[self.nod[el, idx], self.nod[el, idy]] += k[idx][idy]
                    self.mass[self.nod[el, idx], self.nod[el, idy]] += m[idx][idy]

        # print("Writing Out Global Matrices")
        # cmat = open('CurrentMatrix.csv','w'); print("  current matrix")
        # mmat = open('MassMatrix.csv','w'); print("  mass matrix")
        # kmat = open('StiffMatrix.csv','w'); print("  stiffness matrix")
        # for idx in range(0, self.nnodes):
        #     for idy in range(0, self.nnodes):
        #         cmat.write("{0:.5e},".format(self.curr[idx, idy]))
        #         mmat.write("{0:.5e},".format(self.mass[idx, idy]))
        #         kmat.write("{0:.5e},".format(self.stiff[idx, idy]))
        #     cmat.write("\n")
        #     mmat.write("\n")
        #     kmat.write("\n")
        # cmat.close()
        # mmat.close()
        # kmat.close()
        # print("Global RHS")
        # for i in range(0,self.nnodes):
        #     print("{0:.3e} {1:.6e}".format(self.xnod[i], self.rhsf[i]))
        # sys.exit()
        self.soln = zeros(self.nnodes)
        mat = add(self.curr, add(self.stiff, self.mass))
        # print("Writing Out Global Matrix")
        # gmat = open('GlobalMatrix.csv','w'); print("  global matrix")
        # for idx in range(0, self.nnodes):
        #     for idy in range(0, self.nnodes):
        #         gmat.write("{0:.5e},".format(mat[idx, idy]))
        #     gmat.write("\n")
        # gmat.close()
        # sys.exit()
        if ((self.selection == 0) or (self.selection == 1) or (self.selection == 2) or (self.selection == 3) or (self.selection == 5)):
            self.soln[0] = self.u(self.bounds[0])
            self.soln[-1] = self.u(self.bounds[-1])
            subtract(self.rhsf, dot(mat, self.soln), out=self.rhsf) # used for non-zero Dirichlet BCs
            self.soln[1:-1] = linalg.solve(mat[1:-1, 1:-1], self.rhsf[1:-1])
        elif self.selection == 6:
            # if Dirichlet boundary conditions eliminate known values from the system
            self.soln[0] = self.u(self.bounds[0])
            subtract(self.rhsf, dot(mat, self.soln), out=self.rhsf) # used for non-zero Dirichlet BCs
            self.soln[1:] = linalg.solve(mat[1:, 1:], self.rhsf[1:])
        else:
            self.soln = linalg.solve(mat, self.rhsf)
Exemple #8
0
    def CFEM_1D(self):
        """
        Solves a two-point BVP using Galerkin finite elements
        - automatically switches between continuous or discontinuous 
          based on mesh it has access to
        """
        nw, xw, w = QP(self.maxord)

        ## set up matrix and rhs of linear system
        self.stiff = zeros((self.nnodes, self.nnodes))
        self.mass = zeros((self.nnodes, self.nnodes))
        self.rhsf = zeros( self.nnodes )
        for el in range(0, self.nels):
            xL = self.xnod[self.nod[el, 0]]
            xR = self.xnod[self.nod[el, self.order[el]-1]]
            dx = (xR - xL)/2.0
            # compute element stiffness matrix and rhs (load) vector
            k = zeros((self.order[el], self.order[el]))  # element stiffness matrix
            m = zeros((self.order[el], self.order[el]))  # element mass matrix
            f = zeros(self.order[el])     # element load vector

            for l in range(0, nw):
                # x runs in true element, xw runs in reference element
                x = xL + (1.0 + xw[l])*dx
                # calculations on ref element
                psi, dpsi = shape(xw[l], self.order[el])
                Dval = self.D(x)
                SigAbs = self.SigA(x)
                fval = self.f(x)
                f += fval * psi * w[l]*dx
                k += Dval*outer(dpsi, dpsi)/dx/dx * w[l]*dx
                m += SigAbs*outer(psi, psi) * w[l]*dx

            # # uncomment to see the local (stiffness+mass) matrix and local load vector
            # print(k)
            # print(m)
            # print(f)
            # sys.exit()

            for idx in range(0, self.order[el]):
                self.rhsf[self.nod[el, idx]] += f[idx]
                for idy in range(0, self.order[el]):
                    self.stiff[self.nod[el, idx], self.nod[el, idy]] += k[idx][idy]
                    self.mass[self.nod[el, idx], self.nod[el, idy]] += m[idx][idy]

        self.soln = zeros(self.nnodes)
        mat = add(self.stiff, self.mass)
        # SOLVE! (for coefficients of finite elements, still not the \emph{actual} solution)
        if ((self.selection == 0) or (self.selection == 1) or (self.selection == 2) or (self.selection == 3) or (self.selection == 5)):
            # if Dirichlet boundary conditions eliminate known values from the system
            self.soln[0] = self.u(self.bounds[0])
            self.soln[-1] = self.u(self.bounds[-1])
            subtract(self.rhsf, dot(mat, self.soln), out=self.rhsf) # used for non-zero Dirichlet BCs
            self.soln[1:-1] = linalg.solve(mat[1:-1, 1:-1], self.rhsf[1:-1])
        elif self.selection == 6:
            # if Dirichlet boundary conditions eliminate known values from the system
            self.soln[0] = self.u(self.bounds[0])
            subtract(self.rhsf, dot(mat, self.soln), out=self.rhsf) # used for non-zero Dirichlet BCs
            self.soln[1:] = linalg.solve(mat[1:, 1:], self.rhsf[1:])
        else:
            # if Reflecting BCs
            self.soln = linalg.solve(mat, self.rhsf)