def LocallyInjectiveHessian(J, gJ, HJ):
    H1 = 6. * (2 * J**4 - 8 * J**3 + 12 * J**2 - 9 * J +
               3) / (J**3 * (J**6 - 9 * J**5 + 36 * J**4 - 81 * J**3 +
                             108 * J**2 - 81 * J + 27)) * np.outer(gJ, gJ)
    H1 += 3. * (-J**2 + 2 * J - 1) / (J**2 * (J**2 - 3 * J + 3)**2) * HJ
    makezero(H1, 1e-12)
    return H1
def dJdF(F):
    if F.shape[0] == 2:
        return np.array([[F[1, 1], -F[1, 0]], [-F[0, 1], F[0, 0]]])
    else:
        f0 = F[:, 0]
        f1 = F[:, 1]
        f2 = F[:, 2]
        final = np.zeros((3, 3))
        final[:, 0] = np.cross(f1, f2)
        final[:, 1] = np.cross(f2, f0)
        final[:, 2] = np.cross(f0, f1)
        makezero(final)
        return final
    def CauchyStress(self,
                     StrainTensors,
                     ElectricDisplacementx,
                     elem=0,
                     gcounter=0):

        mu = self.mu
        lamb = self.lamb
        d = self.ndim

        I = StrainTensors['I']
        F = StrainTensors['F'][gcounter]
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]

        u, s, vh = svd(F, full_matrices=True)
        vh = vh.T
        R = u.dot(vh.T)
        S = np.dot(vh, np.dot(np.diag(s), vh.T))

        J2 = J**2
        J3 = J**3

        I1 = trace(S)
        I2 = trace(b)

        if self.ndim == 2:
            sigma = 2. * (1. + 1. / J2) * F - 2. * (1. + 1. / J) * R + (
                2. / J2) * (I1 - I2 / J) * dJdF(F)
        else:
            djdf = dJdF(F)
            C = np.dot(F.T, F)
            IC = trace(C)
            IIC = trace(C.dot(C))
            IIStarC = 0.5 * (IC * IC - IIC)
            IS = trace(S)
            # IIS = trace(S.dot(S));
            IIS = I2
            IIStarS = 0.5 * (IS * IS - IIS)

            # % here's symmetric dirichlet
            dIIStarC = 2 * IC * F - 2. * b.dot(F)
            P = 2 * F + dIIStarC / J2 - (2. / J3) * IIStarC * djdf
            P = P - 2 * ((1 + IS / J) * R - (IIStarS / J2) * djdf -
                         (1. / J) * F)
            P = P / 2.
            sigma = P
            makezero(sigma, 1e-12)
            # print(sigma)

        return sigma
Esempio n. 4
0
def remove_duplicates_2D(A, decimals=10):
    """Removes duplicates from floating point 2D array (A) with rounding
    """

    assert isinstance(A,np.ndarray)
    assert (A.dtype == np.float64 or A.dtype == np.float32)

    from Florence.Tensor import makezero
    makezero(A)
    rounded_repoints = np.round(A,decimals=decimals)
    _, idx_repoints, inv_repoints = unique2d(rounded_repoints,order=False,
        consider_sort=False,return_index=True,return_inverse=True)
    A = A[idx_repoints,:]

    return A, idx_repoints, inv_repoints
Esempio n. 5
0
    def ComputeExtrusion(self, nlong=10):
        """Computes extrusion of a base mesh along an arc

            input:
                nlong:                      [int] number of discretisation along
                                            the arc
            returns:
                points:                     [1D array] of discretisation along arc
        """

        from numpy.linalg import norm

        npoints = nlong + 1

        line0 = self.start - self.center
        line1 = self.end - self.center

        # CHECK IF ALL THE POINTS LIE ON A LINE
        if np.isclose(np.abs(self.angle),0.0) or \
            np.isclose(np.abs(self.angle),np.pi) or \
            np.isclose(np.abs(self.angle),2.*np.pi):
            self.angle += 1e-08
            warn("The arc points are nearly colinear")

        t = np.linspace(0, self.angle, npoints + 1)

        points = (np.einsum("i,j",np.sin(self.angle - t),line0) + \
            np.einsum("i,j",np.sin(t),line1))/np.sin(self.angle) + self.center
        makezero(points)

        # IF ALL THE Z-COORDIDATES ARE ZERO, THEN EXTRUSION NOT POSSIBLE
        if np.allclose(points[:, 2], 0.0):
            warn(
                "Third dimension is zero. Extrusion will fail, unless axes are swapped"
            )

        return points
Esempio n. 6
0
    def ComputeExtrusion(self, nlong=10):
        """Computes extrusion of a base mesh along an arc

            input:
                nlong:                      [int] number of discretisation along
                                            the arc
            returns:
                points:                     [1D array] of discretisation along arc
        """

        from numpy.linalg import norm

        npoints = nlong + 1

        line0 = self.start - self.center
        line1 = self.end   - self.center

        # CHECK IF ALL THE POINTS LIE ON A LINE
        if np.isclose(np.abs(self.angle),0.0) or \
            np.isclose(np.abs(self.angle),np.pi) or \
            np.isclose(np.abs(self.angle),2.*np.pi):
            self.angle += 1e-08
            warn("The arc points are nearly colinear")

        t = np.linspace(0,self.angle,npoints+1)

        points = (np.einsum("i,j",np.sin(self.angle - t),line0) + \
            np.einsum("i,j",np.sin(t),line1))/np.sin(self.angle) + self.center
        makezero(points)

        # IF ALL THE Z-COORDIDATES ARE ZERO, THEN EXTRUSION NOT POSSIBLE
        if np.allclose(points[:,2],0.0):
            warn("Third dimension is zero. Extrusion will fail, unless axes are swapped")

        return points




        # # print(tx*self.angle)
        # # FIND NORMAL TO THE PLANE OF ARC
        # normal_to_arc_plane = np.cross(self.start - self.center, self.end - self.center)
        # # FIND TWO ORTHOGONAL VECTORS IN THE PLANE OF ARC
        # X = self.start/norm(self.start)
        # Y = np.cross(normal_to_arc_plane, self.start) / norm(np.cross(normal_to_arc_plane, self.start))
        # # print(normal_to_arc_plane, self.start)
        # # t = np.linspace(0, self.angle, npoints+1)
        # t = np.linspace(0., self.angle, npoints+1)
        # # t = np.linspace(0, self.angle+0.2284, npoints+1)
        # # x = norm(np.dot(self.start - self.center, self.end - self.center))
        # # print(np.arccos(x))
        # # print(self.angle)

        # points = np.einsum("i,j",self.radius*np.cos(t),X) + np.einsum("i,j",self.radius*np.sin(t),Y)
        # # points = np.einsum("i,j",self.radius*np.sin(t),X) + np.einsum("i,j",self.radius*np.cos(t),Y)
        # # y = np.einsum("i,j",self.radius*np.sin(t),Y)
        # # print(X,Y,t)
        # print(points)
        # # print(np.dot(X,Y))

        # # t= np.linspace(-np.pi/2,np.pi,100)
        # # X = np.array([0,1])
        # # Y = np.array([1,0])
        # # # points = np.einsum("i,j",self.radius*np.cos(t),X) + np.einsum("i,j",self.radius*np.sin(t),Y)
        # # points = np.einsum("i,j",self.radius*np.sin(t),X) + np.einsum("i,j",self.radius*np.cos(t),Y)
        # # makezero(points)
        # # print(points)
        # exit()

        # import matplotlib.pyplot as plt
        # plt.plot(points[:,0],points[:,1],'ro')
        # plt.axis('equal')
        # plt.show()

        # import os
        # os.environ['ETS_TOOLKIT'] = 'qt4'
        # from mayavi import mlab

        # figure = mlab.figure(bgcolor=(1,1,1),fgcolor=(1,1,1),size=(800,600))
        # mlab.plot3d(points[:,0],points[:,1],points[:,2])
        # mlab.show()
        # exit()

        # print(self.start_angle, self.end_angle)
        # x = self.radius*np.cos(t)
        # y = self.radius*np.sin(t)


        # points = np.array([x,y]).T.copy()
        # makezero(points)

        # t = np.linspace(0,40.,npoints+1)
Esempio n. 7
0
def HighOrderMeshQuad(C,
                      mesh,
                      Decimals=10,
                      equally_spaced=False,
                      check_duplicates=True,
                      parallelise=False,
                      nCPU=1,
                      compute_boundary_info=True):

    from Florence.FunctionSpace import Quad, QuadES
    from Florence.QuadratureRules import GaussLobattoPointsQuad
    from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPoints
    from Florence.MeshGeneration.NodeArrangement import NodeArrangementQuad

    Parallel = parallelise

    if not equally_spaced:
        eps = GaussLobattoPointsQuad(C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((4, eps.shape[0]), dtype=np.float64)
        for i in range(0, eps.shape[0]):
            Neval[:, i] = Quad.LagrangeGaussLobatto(0,
                                                    eps[i, 0],
                                                    eps[i, 1],
                                                    arrange=1)[:, 0]
    else:
        eps = EquallySpacedPoints(3, C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((4, eps.shape[0]), dtype=np.float64)
        for i in range(0, eps.shape[0]):
            Neval[:, i] = QuadES.Lagrange(0, eps[i, 0], eps[i, 1],
                                          arrange=1)[:, 0]
    makezero(Neval)

    nodeperelem = mesh.elements.shape[1]
    renodeperelem = int((C + 2)**2)
    left_over_nodes = renodeperelem - nodeperelem

    reelements = -1 * np.ones(
        (mesh.elements.shape[0], renodeperelem), dtype=np.int64)
    reelements[:, :4] = mesh.elements
    iesize = int(4 * C + C**2)
    repoints = np.zeros(
        (mesh.points.shape[0] + iesize * mesh.elements.shape[0],
         mesh.points.shape[1]),
        dtype=np.float64)
    repoints[:mesh.points.shape[0], :] = mesh.points

    #--------------------------------------------------------------------------------------
    telements = time()

    xycoord_higher = []
    ParallelTuple1 = []
    if Parallel:
        # GET HIGHER ORDER COORDINATES - PARALLEL
        ParallelTuple1 = parmap.map(ElementLoopTri,
                                    np.arange(0, mesh.elements.shape[0]),
                                    mesh.elements,
                                    mesh.points,
                                    'quad',
                                    eps,
                                    Neval,
                                    pool=MP.Pool(processes=nCPU))

    # LOOP OVER ELEMENTS
    maxNode = np.max(reelements)
    for elem in range(0, mesh.elements.shape[0]):

        # GET HIGHER ORDER COORDINATES
        if Parallel:
            xycoord_higher = ParallelTuple1[elem]
        else:
            xycoord_higher = GetInteriorNodesCoordinates(
                mesh.points[mesh.elements[elem, :], :], 'quad', elem, eps,
                Neval)

        # EXPAND THE ELEMENT CONNECTIVITY
        newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes)
        # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes)
        reelements[elem, 4:] = newElements
        maxNode = newElements[-1]

        repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] +
                 (elem + 1) * iesize] = xycoord_higher[4:, :]

    telements = time() - telements

    #--------------------------------------------------------------------------------------
    # NOW REMOVE DUPLICATED POINTS
    tnodes = time()
    nnode_linear = mesh.points.shape[0]
    # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR
    rounded_repoints = repoints[nnode_linear:, :].copy()
    makezero(rounded_repoints)
    rounded_repoints = np.round(rounded_repoints, decimals=Decimals)
    _, idx_repoints, inv_repoints = unique2d(rounded_repoints,
                                             order=False,
                                             consider_sort=False,
                                             return_index=True,
                                             return_inverse=True)
    del rounded_repoints

    idx_repoints = np.concatenate(
        (np.arange(nnode_linear), idx_repoints + nnode_linear))
    repoints = repoints[idx_repoints, :]

    unique_reelements, inv_reelements = np.unique(reelements[:, 4:],
                                                  return_inverse=True)
    unique_reelements = unique_reelements[inv_repoints]
    reelements = unique_reelements[inv_reelements]
    reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 4)
    reelements = np.concatenate((mesh.elements, reelements), axis=1)

    # SANITY CHECK FOR DUPLICATES
    #---------------------------------------------------------------------#
    # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH
    # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO
    # LINEAR CONNECTIVITY
    if check_duplicates:
        last_shape = repoints.shape[0]
        deci = int(Decimals) - 2
        if Decimals < 6:
            deci = Decimals
        repoints, idx_repoints, inv_repoints = remove_duplicates_2D(
            repoints, decimals=deci)
        unique_reelements, inv_reelements = np.unique(reelements,
                                                      return_inverse=True)
        unique_reelements = unique_reelements[inv_repoints]
        reelements = unique_reelements[inv_reelements]
        reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem)
        if last_shape != repoints.shape[0]:
            warn(
                'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now'
            )
    #---------------------------------------------------------------------#

    tnodes = time() - tnodes
    #------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------
    reedges = np.array([])
    if compute_boundary_info:
        # BUILD EDGES NOW
        tedges = time()

        edge_to_elements = mesh.GetElementsWithBoundaryEdgesQuad()
        node_arranger = NodeArrangementQuad(C)[0]
        reedges = np.zeros((mesh.edges.shape[0], C + 2), dtype=np.int64)
        reedges = reelements[edge_to_elements[:, 0][:, None],
                             node_arranger[edge_to_elements[:, 1], :]]

        tedges = time() - tedges
    #------------------------------------------------------------------------------------------

    class nmesh(object):
        points = repoints
        elements = reelements
        edges = reedges
        faces = []
        nnode = repoints.shape[0]
        nelem = reelements.shape[0]
        info = 'quad'

    # print('\npMeshing timing:\n\t\tElement loop 1:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\
    #  ' seconds'+'\n\t\tElement loop 2:\t '+str(telements_2)+' seconds\n\t\tEdge loop:\t\t '+str(tedges)+' seconds\n')

    return nmesh
Esempio n. 8
0
    def Hessian(self,
                StrainTensors,
                ElectricDisplacementx,
                elem=0,
                gcounter=0):

        mu = self.mu
        lamb = self.lamb
        d = self.ndim

        I = StrainTensors['I']
        F = StrainTensors['F'][gcounter]
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]

        det = np.linalg.det
        u, s, vh = svd(F, full_matrices=True)
        vh = vh.T
        # print(det(u),det(vh))
        # exit()
        if self.ndim == 2:
            s1 = s[0]
            s2 = s[1]
            T = np.array([[0., -1], [1, 0.]])
            s1s2 = s1 + s2
            if (s1s2 < 2.0):
                s1s2 = 2.0
            lamb = 2. / (s1s2)
            T = 1. / np.sqrt(2) * np.dot(u, np.dot(T, vh.T))
            # C_Voigt = 1.0 * ( einsum("ik,jl",I,I)+einsum("il,jk",I,I) ) - 2. * lamb * np.einsum("ij,kl", T, T)
            # C_Voigt = 1./ J * np.einsum("kI,lJ,iIjJ->iklj", F, F, C_Voigt)

            C_Voigt = 2.0 * (einsum("ik,jl", I, I)) - 2. * lamb * np.einsum(
                "ij,kl", T, T)
            # C_Voigt = 2.0 * ( einsum("ij,kl",I,I)) - 2. * lamb * np.einsum("ij,kl", T, T)
            C_Voigt = 1. / J * np.einsum("jJ,iJkL,lL->ijkl", F, C_Voigt, F)
            # Exclude the stress term from this
            R = u.dot(vh.T)
            sigma = 2. * (F - R)
            sigma = 1. / J * np.dot(sigma, F.T)
            C_Voigt -= np.einsum("ij,kl", sigma, I)
            # print(C_Voigt)
            # print(np.linalg.norm(T.flatten()))
            # print(Voigt(np.einsum("ij,kl", T, T),1))
            # print(np.einsum("ij,kl", T, T))
            # exit()

            C_Voigt = np.ascontiguousarray(C_Voigt)

        elif self.ndim == 3:
            s1 = s[0]
            s2 = s[1]
            s3 = s[2]
            T1 = np.array([[0., 0., 0.], [0., 0., -1], [0., 1., 0.]])
            T1 = 1. / np.sqrt(2) * np.dot(u, np.dot(T1, vh.T))
            T2 = np.array([[0., 0., -1], [0., 0., 0.], [1., 0., 0.]])
            T2 = 1. / np.sqrt(2) * np.dot(u, np.dot(T2, vh.T))
            T3 = np.array([[0., -1, 0.], [1., 0., 0.], [0., 0., 0.]])
            T3 = 1. / np.sqrt(2) * np.dot(u, np.dot(T3, vh.T))
            s1s2 = s1 + s2
            s1s3 = s1 + s3
            s2s3 = s2 + s3
            if (s1s2 < 2.0):
                s1s2 = 2.0
            if (s1s3 < 2.0):
                s1s3 = 2.0
            if (s2s3 < 2.0):
                s2s3 = 2.0
            lamb1 = 2. / (s1s2)
            lamb2 = 2. / (s1s3)
            lamb3 = 2. / (s2s3)

            # C_Voigt = 1.0 * ( einsum("ik,jl",I,I)+einsum("il,jk",I,I) ) - 2. * lamb3 * np.einsum("ij,kl", T1, T1) - \
            #     - 2. * lamb2 * np.einsum("ij,kl", T2, T2) - 2. * lamb1 * np.einsum("ij,kl", T3, T3)
            # C_Voigt = 1./ J * np.einsum("kI,lJ,iIjJ->iklj", F, F, C_Voigt)
            # C_Voigt = np.ascontiguousarray(C_Voigt)

            C_Voigt = 2.0 * ( einsum("ik,jl",I,I)) - 2. * lamb3 * np.einsum("ij,kl", T1, T1) - \
                - 2. * lamb2 * np.einsum("ij,kl", T2, T2) - 2. * lamb1 * np.einsum("ij,kl", T3, T3)
            C_Voigt = 1. / J * np.einsum("jJ,iJkL,lL->ijkl", F, C_Voigt, F)
            C_Voigt = np.ascontiguousarray(C_Voigt)

            R = u.dot(vh.T)
            sigma = 2. * (F - R)
            sigma = 1. / J * np.dot(sigma, F.T)
            C_Voigt -= np.einsum("ij,kl", sigma, I)

            # s1 = s[0]
            # s2 = s[1]
            # s3 = s[2]
            # T1 = np.array([[0.,-1.,0.],[1.,0.,0],[0.,0.,0.]])
            # T1 = 1./np.sqrt(2) * np.dot(u, np.dot(T1, vh.T))
            # T2 = np.array([[0.,0.,0.],[0.,0., 1],[0.,-1,0.]])
            # T2 = 1./np.sqrt(2) * np.dot(u, np.dot(T2, vh.T))
            # T3 = np.array([[0.,0.,1.],[0.,0.,0.],[-1,0.,0.]])
            # T3 = 1./np.sqrt(2) * np.dot(u, np.dot(T3, vh.T))
            # s1s2 = s1 + s2
            # s1s3 = s1 + s3
            # s2s3 = s2 + s3
            # # if (s1s2 < 2.0):
            # #     s1s2 = 2.0
            # # if (s1s3 < 2.0):
            # #     s1s3 = 2.0
            # # if (s2s3 < 2.0):
            # #     s2s3 = 2.0
            # lamb1 = 2. / (s1s2)
            # lamb2 = 2. / (s1s3)
            # lamb3 = 2. / (s2s3)

            # # C_Voigt = 1.0 * ( einsum("ik,jl",I,I)+einsum("il,jk",I,I) ) - 2. * lamb1 * np.einsum("ij,kl", T1, T1) - \
            # #     - 2. * lamb3 * np.einsum("ij,kl", T2, T2) - 2. * lamb2 * np.einsum("ij,kl", T3, T3)
            # # C_Voigt = 1./ J * np.einsum("kI,lJ,iIjJ->iklj", F, F, C_Voigt)
            # # C_Voigt = np.ascontiguousarray(C_Voigt)

            # C_Voigt = 2.0 * ( einsum("ik,jl",I,I)) - 2. * lamb1 * np.einsum("ij,kl", T1, T1) - \
            #     - 2. * lamb3 * np.einsum("ij,kl", T2, T2) - 2. * lamb2 * np.einsum("ij,kl", T3, T3)
            # C_Voigt = 1./ J * np.einsum("kI,lJ,iIjJ->iklj", F, F, C_Voigt)
            # C_Voigt = np.ascontiguousarray(C_Voigt)

            # R = u.dot(vh.T)
            # sigma = 2. * (F - R)
            # sigma = 1./J * np.dot(sigma, F.T)
            # C_Voigt -= np.einsum("ij,kl",sigma,I)

        C_Voigt = Voigt(C_Voigt, 1)
        makezero(C_Voigt)

        # C_Voigt = np.eye(3,3)*2

        # C_Voigt += 0.05*self.vIikIjl
        # print(C_Voigt)
        # s = svd(C_Voigt)[1]
        # print(s)

        return C_Voigt
Esempio n. 9
0
def NodeArrangementQuadToTri(C):

    nsize = int((C + 2) * (C + 3) / 2.)
    node_arranger = np.zeros((2, nsize), dtype=np.int64)
    if C == 0:
        node_arranger[0, :] = [0, 1, 3]
        node_arranger[1, :] = [1, 2, 3]
    elif C == 1:
        node_arranger[0, :] = [0, 1, 3, 4, 5, 6]
        node_arranger[1, :] = [1, 2, 3, 7, 6, 8]
    elif C == 2:
        node_arranger[0, :] = [0, 1, 3, 4, 5, 6, 7, 8, 10, 11]
        node_arranger[1, :] = [1, 2, 3, 9, 13, 8, 12, 15, 11, 14]
    elif C == 3:
        node_arranger[0, :] = [
            0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 17, 18
        ]
        node_arranger[1, :] = [
            1, 2, 3, 11, 16, 21, 10, 15, 20, 24, 14, 19, 23, 18, 22
        ]
    elif C == 4:
        node_arranger[0, :] = [
            0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 20, 21, 22,
            26, 27
        ]
        node_arranger[1, :] = [
            1, 2, 3, 13, 19, 25, 31, 12, 18, 24, 30, 35, 17, 23, 29, 34, 22,
            28, 33, 27, 32
        ]
    elif C == 5:
        node_arranger[0, :] = [
            0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20,
            23, 24, 25, 26, 30, 31, 32, 37, 38
        ]
        node_arranger[1, :] = [
            1, 2, 3, 15, 22, 29, 36, 43, 14, 21, 28, 35, 42, 48, 20, 27, 34,
            41, 47, 26, 33, 40, 46, 32, 39, 45, 38, 44
        ]
    else:
        raise NotImplementedError(
            'Conversion beynond p=6 nodes not implemented yet')
        # THIS FLOATING POINT APPROACH COMAPRES TRI AND QUAD
        # POINTS TO GET NUMBERING, BUT DOESNOT WORK FOR NOT
        # EQUALLY DISTANCED POINTS AS FEKETE POINTS ON TRIS
        # DON'T MATCH GAUSS LOBATTO POINTS OF QUADS FOR THE
        # INTERIOR NODES
        from .GaussLobattoPoints import GaussLobattoPointsQuad
        from .FeketePointsTri import FeketePointsTri
        from Florence.Tensor import in2d, makezero, unique2d

        epst = FeketePointsTri(C)
        epsq = GaussLobattoPointsQuad(C)

        makezero(epst, tol=1e-12)
        makezero(epsq, tol=1e-12)

        aranger = np.arange(int((C + 2)**2))
        # makezero(epst) # TAKES CARE OF -0. AND +0. FOR IN2D
        # T1_idx = in2d(epsq,epst)
        # T1 = aranger[T1_idx]
        T1 = np.array(__QuadToTriArrangement__(epsq, epst))

        # MAP THE OTHER TRIANGLE
        # MAP: x_n = -y; y_n = 1+x+y
        epst_mirror = np.zeros_like(epst)
        epst_mirror[:, 0] = -epst[:, 1]
        epst_mirror[:, 1] = 1 + epst[:, 0] + epst[:, 1]
        # makezero(epst_mirror) # TAKES CARE OF -0. AND +0. FOR IN2D
        T2 = np.array(__QuadToTriArrangement__(epsq, epst_mirror))

        node_arranger[0, :] = T1
        node_arranger[1, :] = T2

    return node_arranger
    def GetLocalStiffness(self,
                          function_space,
                          material,
                          LagrangeElemCoords,
                          EulerElemCoords,
                          fem_solver,
                          elem=0):
        """Get stiffness matrix of the system"""

        nvar = self.nvar
        ndim = self.ndim
        nodeperelem = function_space.Bases.shape[0]

        det = np.linalg.det
        inv = np.linalg.inv
        Jm = function_space.Jm
        AllGauss = function_space.AllGauss

        # ALLOCATE
        stiffness = np.zeros((nodeperelem * nvar, nodeperelem * nvar),
                             dtype=np.float64)
        tractionforce = np.zeros((nodeperelem * nvar, 1), dtype=np.float64)
        B = np.zeros((nodeperelem * nvar, material.H_VoigtSize),
                     dtype=np.float64)

        # COMPUTE KINEMATIC MEASURES AT ALL INTEGRATION POINTS USING EINSUM (AVOIDING THE FOR LOOP)
        # MAPPING TENSOR [\partial\vec{X}/ \partial\vec{\varepsilon} (ndim x ndim)]
        ParentGradientX = np.einsum('ijk,jl->kil', Jm, LagrangeElemCoords)
        # ParentGradientX = [np.eye(3,3)]
        # MATERIAL GRADIENT TENSOR IN PHYSICAL ELEMENT [\nabla_0 (N)]
        MaterialGradient = np.einsum('ijk,kli->ijl', inv(ParentGradientX), Jm)
        # DEFORMATION GRADIENT TENSOR [\vec{x} \otimes \nabla_0 (N)]
        F = np.einsum('ij,kli->kjl', EulerElemCoords, MaterialGradient)

        # COMPUTE REMAINING KINEMATIC MEASURES
        StrainTensors = KinematicMeasures(F, fem_solver.analysis_nature)

        # SPATIAL GRADIENT AND MATERIAL GRADIENT TENSORS ARE EQUAL
        SpatialGradient = np.einsum('ikj', MaterialGradient)
        # COMPUTE ONCE detJ
        detJ = np.einsum('i,i->i', AllGauss[:, 0], det(ParentGradientX))
        # detJ = np.einsum('i,i,i->i', AllGauss[:,0], det(ParentGradientX), StrainTensors['J'])

        # LOOP OVER GAUSS POINTS
        for counter in range(AllGauss.shape[0]):

            # COMPUTE THE HESSIAN AT THIS GAUSS POINT
            H_Voigt = material.Hessian(StrainTensors, None, elem, counter)

            # COMPUTE CAUCHY STRESS TENSOR
            CauchyStressTensor = []
            if fem_solver.requires_geometry_update:
                CauchyStressTensor = material.CauchyStress(
                    StrainTensors, None, elem, counter)

            # COMPUTE THE TANGENT STIFFNESS MATRIX
            BDB_1, t = self.ConstitutiveStiffnessIntegrand(
                B,
                SpatialGradient[counter, :, :],
                StrainTensors['F'][counter],
                CauchyStressTensor,
                H_Voigt,
                requires_geometry_update=fem_solver.requires_geometry_update)

            # INTEGRATE TRACTION FORCE
            if fem_solver.requires_geometry_update:
                tractionforce += t * detJ[counter]

            # INTEGRATE STIFFNESS
            stiffness += BDB_1 * detJ[counter]

        makezero(stiffness, 1e-12)
        # print(stiffness)
        # print(tractionforce)
        # exit()
        return stiffness, tractionforce
Esempio n. 11
0
def PointInversionIsoparametricFEM(element_type,
                                   C,
                                   LagrangeElemCoords,
                                   point,
                                   equally_spaced=False,
                                   tolerance=1.0e-7,
                                   maxiter=20,
                                   verbose=False,
                                   use_simple_bases=False,
                                   initial_guess=None):
    """ This is the inverse isoparametric map, in that given a physical point,
        find the isoparametric coordinates, provided that the coordinates of
        physical element 'LagrangeElemCoords' is known

        input:
            point:                  [2S(3D) vector] containing X,Y,(Z) value of the physical point
        return:
            iso_parametric_point    [2S(3D) vector] containing X,Y,(Z) value of the parametric point
            convergence_info        [boolean] if the iteration converged or not
    """

    from Florence.FunctionSpace import Tri, Tet, Quad, QuadES, Hex, HexES, Pent
    from Florence.Tensor import makezero

    # INITIAL GUESS - VERY IMPORTANT
    if initial_guess is None:
        if use_simple_bases:
            p_isoparametric = np.zeros(LagrangeElemCoords.shape[1])
        else:
            p_isoparametric = -np.ones(LagrangeElemCoords.shape[1])
    else:
        p_isoparametric = initial_guess
    residual = 0.
    blow_up_value = 1e10
    convergence_info = False

    for niter in range(maxiter):

        # Using the current iterative solution of isoparametric coordinate evaluate bases and gradient of bases
        if element_type == "tet":
            if not use_simple_bases:
                Neval, gradient = Tet.hpNodal.hpBases(
                    C,
                    p_isoparametric[0],
                    p_isoparametric[1],
                    p_isoparametric[2],
                    False,
                    1,
                    equally_spaced=equally_spaced)
            else:
                Neval, gradient = hpBasesTetSimple(p_isoparametric[0],
                                                   p_isoparametric[1],
                                                   p_isoparametric[2])
        elif element_type == "hex":
            if not equally_spaced:
                Neval = Hex.LagrangeGaussLobatto(C, p_isoparametric[0],
                                                 p_isoparametric[1],
                                                 p_isoparametric[2]).flatten()
                gradient = Hex.GradLagrangeGaussLobatto(
                    C, p_isoparametric[0], p_isoparametric[1],
                    p_isoparametric[2])
            else:
                Neval = HexES.Lagrange(C, p_isoparametric[0],
                                       p_isoparametric[1],
                                       p_isoparametric[2]).flatten()
                gradient = HexES.GradLagrange(C, p_isoparametric[0],
                                              p_isoparametric[1],
                                              p_isoparametric[2])
        elif element_type == "tri":
            if not use_simple_bases:
                Neval, gradient = Tri.hpNodal.hpBases(
                    C,
                    p_isoparametric[0],
                    p_isoparametric[1],
                    True,
                    1,
                    equally_spaced=equally_spaced)
            else:
                Neval, gradient = hpBasesTriSimple(p_isoparametric[0],
                                                   p_isoparametric[1])
        elif element_type == "quad":
            if not use_simple_bases:
                if not equally_spaced:
                    Neval = Quad.LagrangeGaussLobatto(
                        C, p_isoparametric[0], p_isoparametric[1]).flatten()
                    gradient = Quad.GradLagrangeGaussLobatto(
                        C, p_isoparametric[0], p_isoparametric[1])
                else:
                    Neval = QuadES.Lagrange(C, p_isoparametric[0],
                                            p_isoparametric[1]).flatten()
                    gradient = QuadES.GradLagrange(C, p_isoparametric[0],
                                                   p_isoparametric[1])
            else:
                Neval, gradient = hpBasesQuadSimple(p_isoparametric[0],
                                                    p_isoparametric[1])
        elif element_type == "pent":
            Neval, gradient = Pent.PentBases(C, p_isoparametric[0],
                                             p_isoparametric[1])

        makezero(np.atleast_2d(Neval))
        makezero(gradient)

        # Find the residual X - X(N) [i.e. point - FEM interpolated point]
        residual = point - np.dot(Neval, LagrangeElemCoords)
        # print(np.dot(Neval,LagrangeElemCoords))
        # Find the isoparametric (Jacobian) matrix dX/d\Xi
        ParentGradientX = np.dot(gradient.T, LagrangeElemCoords)
        # ParentGradientX = np.fliplr(ParentGradientX)
        # Solve and update incremental solution
        old_p_isoparametric = np.copy(p_isoparametric)
        # print(p_isoparametric)
        try:
            # p_isoparametric += np.dot(np.linalg.inv(ParentGradientX), residual)
            p_isoparametric += np.linalg.solve(ParentGradientX, residual)
        except:
            convergence_info = False
            break

        # CHECK IF WITHIN TOLERANCE
        if norm(p_isoparametric - old_p_isoparametric) < tolerance:
            convergence_info = True
            break
        # print(norm(residual))
        if norm(residual) < tolerance * 1e2:
            convergence_info = True
            break
        # OTHERWISE DEAL WITH BLOW UP SITUATION
        if np.isnan(norm(residual)) > blow_up_value or norm(
                residual) > blow_up_value:
            break
        if np.isnan(norm(
                p_isoparametric)) or norm(p_isoparametric) > blow_up_value:
            break

    if verbose:
        return p_isoparametric, convergence_info
    return p_isoparametric
Esempio n. 12
0
def HighOrderMeshLine(C,
                      mesh,
                      Decimals=10,
                      equally_spaced=False,
                      check_duplicates=True,
                      Parallel=False,
                      nCPU=1):

    from Florence.FunctionSpace import Line
    from Florence.QuadratureRules import GaussLobattoPoints1D
    from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPoints
    from Florence.MeshGeneration.NodeArrangement import NodeArrangementLine

    # ARRANGE NODES FOR LINES HERE (DONE ONLY FOR LINES) - IMPORTANT
    node_aranger = NodeArrangementLine(C)

    if not equally_spaced:
        eps = GaussLobattoPoints1D(C).ravel()
        eps = eps[node_aranger]
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((2, eps.shape[0]), dtype=np.float64)
        for i in range(0, eps.shape[0]):
            Neval[:, i] = Line.LagrangeGaussLobatto(0, eps[i])[0]
    else:
        eps = EquallySpacedPoints(2, C).ravel()
        eps = eps[node_aranger]
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((2, eps.shape[0]), dtype=np.float64)
        for i in range(0, eps.shape[0]):
            Neval[:, i] = Line.Lagrange(0, eps[i])[0]
    makezero(Neval)

    nodeperelem = mesh.elements.shape[1]
    renodeperelem = int(C + 2)
    left_over_nodes = renodeperelem - nodeperelem

    reelements = -1 * np.ones(
        (mesh.elements.shape[0], renodeperelem), dtype=np.int64)
    reelements[:, :2] = mesh.elements
    iesize = int(C)
    repoints = np.zeros(
        (mesh.points.shape[0] + iesize * mesh.elements.shape[0],
         mesh.points.shape[1]),
        dtype=np.float64)
    repoints[:mesh.points.shape[0], :] = mesh.points

    #--------------------------------------------------------------------------------------
    telements = time()

    xycoord_higher = []
    ParallelTuple1 = []
    if Parallel:
        # GET HIGHER ORDER COORDINATES - PARALLEL
        ParallelTuple1 = parmap.map(ElementLoopTri,
                                    np.arange(0, mesh.elements.shape[0]),
                                    mesh.elements,
                                    mesh.points,
                                    'line',
                                    eps,
                                    Neval,
                                    pool=MP.Pool(processes=nCPU))

    # LOOP OVER ELEMENTS
    maxNode = np.max(reelements)
    for elem in range(0, mesh.elements.shape[0]):

        # GET HIGHER ORDER COORDINATES
        if Parallel:
            xycoord_higher = ParallelTuple1[elem]
        else:
            xycoord_higher = GetInteriorNodesCoordinates(
                mesh.points[mesh.elements[elem, :], :], 'line', elem, eps,
                Neval)

        # EXPAND THE ELEMENT CONNECTIVITY
        newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes)
        # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes)
        reelements[elem, 2:] = newElements
        maxNode = newElements[-1]

        repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] +
                 (elem + 1) * iesize] = xycoord_higher[2:, :]

    telements = time() - telements

    #--------------------------------------------------------------------------------------
    # NOW REMOVE DUPLICATED POINTS
    tnodes = time()
    nnode_linear = mesh.points.shape[0]
    # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR
    rounded_repoints = repoints[nnode_linear:, :].copy()
    makezero(rounded_repoints)
    rounded_repoints = np.round(rounded_repoints, decimals=Decimals)
    _, idx_repoints, inv_repoints = unique2d(rounded_repoints,
                                             order=False,
                                             consider_sort=False,
                                             return_index=True,
                                             return_inverse=True)
    del rounded_repoints

    idx_repoints = np.concatenate(
        (np.arange(nnode_linear), idx_repoints + nnode_linear))
    repoints = repoints[idx_repoints, :]

    unique_reelements, inv_reelements = np.unique(reelements[:, 2:],
                                                  return_inverse=True)
    unique_reelements = unique_reelements[inv_repoints]
    reelements = unique_reelements[inv_reelements]
    reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 2)
    reelements = np.concatenate((mesh.elements, reelements), axis=1)

    # SANITY CHECK FOR DUPLICATES
    #---------------------------------------------------------------------#
    # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH
    # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO
    # LINEAR CONNECTIVITY
    if check_duplicates:
        last_shape = repoints.shape[0]
        deci = int(Decimals) - 2
        if Decimals < 6:
            deci = Decimals
        repoints, idx_repoints, inv_repoints = remove_duplicates_2D(
            repoints, decimals=deci)
        unique_reelements, inv_reelements = np.unique(reelements,
                                                      return_inverse=True)
        unique_reelements = unique_reelements[inv_repoints]
        reelements = unique_reelements[inv_reelements]
        reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem)
        if last_shape != repoints.shape[0]:
            warn(
                'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now'
            )
    #---------------------------------------------------------------------#

    tnodes = time() - tnodes

    #------------------------------------------------------------------------------------------

    class nmesh(object):
        points = repoints
        elements = reelements
        edges = []
        faces = []
        nnode = repoints.shape[0]
        nelem = reelements.shape[0]
        info = 'line'

    # MESH CORNERS REMAIN THE SAME FOR ALL POLYNOMIAL DEGREES
    if isinstance(mesh.corners, np.ndarray):
        nmesh.corners = mesh.corners

    return nmesh
Esempio n. 13
0
>>>>>>> upstream/master
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((2,eps.shape[0]),dtype=np.float64)
        for i in range(0,eps.shape[0]):
            Neval[:,i] = Line.LagrangeGaussLobatto(0,eps[i])[0]
    else:
        eps = EquallySpacedPoints(2,C).ravel()
<<<<<<< HEAD
=======
        eps = eps[node_aranger]
>>>>>>> upstream/master
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((2,eps.shape[0]),dtype=np.float64)
        for i in range(0,eps.shape[0]):
            Neval[:,i] = Line.Lagrange(0,eps[i])[0]
    makezero(Neval)

<<<<<<< HEAD
=======

>>>>>>> upstream/master
    nodeperelem = mesh.elements.shape[1]
    renodeperelem = int(C+2)
    left_over_nodes = renodeperelem - nodeperelem

    reelements = -1*np.ones((mesh.elements.shape[0],renodeperelem),dtype=np.int64)
    reelements[:,:2] = mesh.elements
    iesize = int(C)
    repoints = np.zeros((mesh.points.shape[0]+iesize*mesh.elements.shape[0],mesh.points.shape[1]),dtype=np.float64)
    repoints[:mesh.points.shape[0],:]=mesh.points
    def GetIdealElement(self, elem, fem_solver, function_space,
                        LagrangeElemCoords):
        """Retrieves ideal element/domain
        """

        from Florence.Tensor import makezero
        from Florence.FunctionSpace import Tri, Tet, Quad, Hex
        from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPoints, EquallySpacedPointsTri, EquallySpacedPointsTet
        sqrt = np.sqrt
        if function_space.element_type == "tri":
            nodeperlinearelem = 3
            eps = EquallySpacedPointsTri(function_space.degree - 1)
            hpBases = Tri.hpNodal.hpBases
            Neval = np.zeros((nodeperlinearelem, eps.shape[0]),
                             dtype=np.float64)
            for i in range(0, eps.shape[0]):
                Neval[:, i] = hpBases(0,
                                      eps[i, 0],
                                      eps[i, 1],
                                      Transform=1,
                                      EvalOpt=1,
                                      equally_spaced=True)[0]
            xycoord = LagrangeElemCoords[:nodeperlinearelem, :]
            xycoord = np.array([[-0.5, 0], [0.5, 0], [0., np.sqrt(3.) / 2.]])
            # xycoord = eps[:nodeperlinearelem,:]
            # xycoord = fem_solver.imesh.points[elem,:]

        elif function_space.element_type == "quad":
            nodeperlinearelem = 4
            eps = EquallySpacedPoints(3, function_space.degree - 1)
            hpBases = Quad.LagrangeGaussLobatto
            Neval = np.zeros((nodeperlinearelem, eps.shape[0]),
                             dtype=np.float64)
            for i in range(0, eps.shape[0]):
                Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], arrange=1)[:, 0]
            xycoord = LagrangeElemCoords[:nodeperlinearelem, :]
            xycoord = np.array([[0., 0], [1., 0], [1., 1.], [0., 1.]])
            xycoord = eps[:nodeperlinearelem, :]

        elif function_space.element_type == "tet":
            nodeperlinearelem = 4
            eps = EquallySpacedPointsTet(function_space.degree - 1)
            hpBases = Tet.hpNodal.hpBases
            Neval = np.zeros((nodeperlinearelem, eps.shape[0]),
                             dtype=np.float64)
            for i in range(0, eps.shape[0]):
                Neval[:, i] = hpBases(0,
                                      eps[i, 0],
                                      eps[i, 1],
                                      eps[i, 2],
                                      Transform=1,
                                      EvalOpt=1,
                                      equally_spaced=True)[0]
            xycoord = LagrangeElemCoords[:nodeperlinearelem, :]
            xycoord = np.array([[sqrt(8. / 9.), 0, -1 / 3.],
                                [-sqrt(2. / 9.),
                                 sqrt(2. / 3.), -1 / 3.],
                                [-sqrt(2. / 9.), -sqrt(2. / 3.), -1 / 3.],
                                [0., 0, 1.]])

        elif function_space.element_type == "hex":
            nodeperlinearelem = 8
            eps = EquallySpacedPoints(4, function_space.degree - 1)
            hpBases = Hex.LagrangeGaussLobatto
            Neval = np.zeros((nodeperlinearelem, eps.shape[0]),
                             dtype=np.float64)
            for i in range(0, eps.shape[0]):
                Neval[:, i] = hpBases(0,
                                      eps[i, 0],
                                      eps[i, 1],
                                      eps[i, 2],
                                      arrange=1)[:, 0]
            xycoord = LagrangeElemCoords[:nodeperlinearelem, :]
            xycoord = eps[:nodeperlinearelem, :]

        makezero(Neval)
        xycoord_higher = np.copy(LagrangeElemCoords)
        xycoord_higher[:nodeperlinearelem, :] = xycoord
        if function_space.degree > 1:
            xycoord_higher[nodeperlinearelem:, :] = np.dot(
                Neval[:, nodeperlinearelem:].T, xycoord)
        LagrangeElemCoords = xycoord_higher

        return LagrangeElemCoords
Esempio n. 15
0
def HighOrderMeshTri_SEMISTABLE(C,
                                mesh,
                                Decimals=10,
                                equally_spaced=False,
                                check_duplicates=True,
                                Parallel=False,
                                nCPU=1,
                                ComputeAll=False):

    from Florence.FunctionSpace import Tri
    from Florence.QuadratureRules.FeketePointsTri import FeketePointsTri
    from Florence.MeshGeneration.NodeArrangement import NodeArrangementTri

    # SWITCH OFF MULTI-PROCESSING FOR SMALLER PROBLEMS WITHOUT GIVING A MESSAGE
    if (mesh.elements.shape[0] < 1000) and (C < 8):
        Parallel = False
        nCPU = 1

    if not equally_spaced:
        eps = FeketePointsTri(C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        hpBases = Tri.hpNodal.hpBases
        Neval = np.zeros((3, eps.shape[0]), dtype=np.float64)
        for i in range(3, eps.shape[0]):
            Neval[:, i] = hpBases(0, eps[i, 0], eps[i, 1], 1)[0]
    else:
        from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPointsTri
        eps = EquallySpacedPointsTri(C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        hpBases = Tri.hpNodal.hpBases
        Neval = np.zeros((3, eps.shape[0]), dtype=np.float64)
        for i in range(3, eps.shape[0]):
            Neval[:, i] = hpBases(0,
                                  eps[i, 0],
                                  eps[i, 1],
                                  Transform=1,
                                  EvalOpt=1,
                                  equally_spaced=True)[0]

    # THIS IS NECESSARY FOR REMOVING DUPLICATES
    makezero(Neval, tol=1e-12)

    nodeperelem = mesh.elements.shape[1]
    renodeperelem = int((C + 2.) * (C + 3.) / 2.)
    left_over_nodes = renodeperelem - nodeperelem

    reelements = -1 * np.ones(
        (mesh.elements.shape[0], renodeperelem), dtype=np.int64)
    reelements[:, :3] = mesh.elements
    iesize = int(C * (C + 5.) / 2.)
    repoints = np.zeros(
        (mesh.points.shape[0] + iesize * mesh.elements.shape[0],
         mesh.points.shape[1]),
        dtype=np.float64)
    # repoints[:mesh.points.shape[0],:]=mesh.points[:,:2]
    repoints[:mesh.points.shape[0], :] = mesh.points

    pshape0, pshape1 = mesh.points.shape[0], mesh.points.shape[1]
    repshape0, repshape1 = repoints.shape[0], repoints.shape[1]

    telements = time()

    xycoord_higher = []
    ParallelTuple1 = []
    if Parallel:
        # GET HIGHER ORDER COORDINATES - PARALLEL
        ParallelTuple1 = parmap.map(ElementLoopTri,
                                    np.arange(0, mesh.elements.shape[0]),
                                    mesh.elements,
                                    mesh.points,
                                    'tri',
                                    eps,
                                    Neval,
                                    pool=MP.Pool(processes=nCPU))

    # LOOP OVER ELEMENTS
    maxNode = np.max(reelements)
    for elem in range(0, mesh.elements.shape[0]):

        # GET HIGHER ORDER COORDINATES
        if Parallel:
            xycoord_higher = ParallelTuple1[elem]
        else:
            # xycoord =  mesh.points[mesh.elements[elem,:],:]
            xycoord_higher = GetInteriorNodesCoordinates(
                mesh.points[mesh.elements[elem, :], :], 'tri', elem, eps,
                Neval)

        # EXPAND THE ELEMENT CONNECTIVITY
        newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes)
        # reelements[elem,3:] = np.arange(maxNode+1,maxNode+1+left_over_nodes)
        reelements[elem, 3:] = newElements
        maxNode = newElements[-1]

        repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] +
                 (elem + 1) * iesize] = xycoord_higher[3:, :]

    telements = time() - telements

    #--------------------------------------------------------------------------------------
    # NOW REMOVE DUPLICATED POINTS
    tnodes = time()
    nnode_linear = mesh.points.shape[0]
    # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR
    rounded_repoints = repoints[nnode_linear:, :].copy()
    makezero(rounded_repoints)
    rounded_repoints = np.round(rounded_repoints, decimals=Decimals)
    # flattened_repoints = np.ascontiguousarray(rounded_repoints).view(np.dtype((np.void,
    # rounded_repoints.dtype.itemsize * rounded_repoints.shape[1])))
    # _, idx_repoints, inv_repoints = np.unique(flattened_repoints,return_index=True,return_inverse=True)
    _, idx_repoints, inv_repoints = unique2d(rounded_repoints,
                                             order=False,
                                             consider_sort=False,
                                             return_index=True,
                                             return_inverse=True)
    del rounded_repoints

    idx_repoints = np.concatenate(
        (np.arange(nnode_linear), idx_repoints + nnode_linear))
    repoints = repoints[idx_repoints, :]

    unique_reelements, inv_reelements = np.unique(reelements[:, 3:],
                                                  return_inverse=True)
    unique_reelements = unique_reelements[inv_repoints]
    reelements = unique_reelements[inv_reelements]
    reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 3)
    reelements = np.concatenate((mesh.elements, reelements), axis=1)

    # SANITY CHECK FOR DUPLICATES
    #---------------------------------------------------------------------#
    # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH
    # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO
    # LINEAR CONNECTIVITY
    if check_duplicates:
        last_shape = repoints.shape[0]
        deci = int(Decimals) - 2
        if Decimals < 6:
            deci = Decimals
        repoints, idx_repoints, inv_repoints = remove_duplicates_2D(
            repoints, decimals=deci)
        unique_reelements, inv_reelements = np.unique(reelements,
                                                      return_inverse=True)
        unique_reelements = unique_reelements[inv_repoints]
        reelements = unique_reelements[inv_reelements]
        reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem)
        if last_shape != repoints.shape[0]:
            warn(
                'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now'
            )
    #---------------------------------------------------------------------#

    tnodes = time() - tnodes
    #------------------------------------------------------------------------------------------

    # BUILD EDGES NOW
    #------------------------------------------------------------------------------------------
    tedges = time()

    edge_to_elements = mesh.GetElementsWithBoundaryEdgesTri()
    node_arranger = NodeArrangementTri(C)[0]
    reedges = np.zeros((mesh.edges.shape[0], C + 2), dtype=np.int64)
    # for i in range(mesh.edges.shape[0]):
    # reedges[i,:] = reelements[edge_to_elements[i,0],node_arranger[edge_to_elements[i,1],:]]
    reedges = reelements[edge_to_elements[:, 0][:, None],
                         node_arranger[edge_to_elements[:, 1], :]]

    tedges = time() - tedges

    #------------------------------------------------------------------------------------------

    class nmesh(object):
        # """Construct pMesh"""
        points = repoints
        elements = reelements
        edges = reedges
        faces = np.array([[], []])
        nnode = repoints.shape[0]
        nelem = reelements.shape[0]
        info = 'tri'

    # print '\npMeshing timing:\n\t\tElement loop 1:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\
    #  ' seconds'+'\n\t\tElement loop 2:\t '+str(telements_2)+' seconds\n\t\tEdge loop:\t\t '+str(tedges)+' seconds\n'

    return nmesh
    def Hessian(self,
                StrainTensors,
                ElectricDisplacementx,
                elem=0,
                gcounter=0):

        mu = self.mu
        lamb = self.lamb
        d = self.ndim

        I = StrainTensors['I']
        F = StrainTensors['F'][gcounter]
        J = StrainTensors['J'][gcounter]
        b = StrainTensors['b'][gcounter]

        det = np.linalg.det
        u, s, vh = svd(F, full_matrices=True)
        # u, s, vh = np.linalg.svd(F, full_matrices=True)
        vh = vh.T
        # print(u)
        # print(s)
        # print(vh)
        # exit()

        R = u.dot(vh.T)
        S = np.dot(vh, np.dot(np.diag(s), vh.T))
        g = vec(dJdF(F))

        J2 = J**2
        J3 = J**3
        J4 = J**4

        f = vec(F)
        r = vec(R)
        HJ = d2JdFdF(F)

        if self.ndim == 2:

            # HJ = np.eye(4,4); HJ = np.fliplr(HJ); HJ[1,2] = -1; HJ[2,1] = -1;
            I1 = trace(S)
            I2 = trace(b)

            T = np.array([[0., -1], [1, 0.]])
            T = 1. / np.sqrt(2.) * np.dot(u, np.dot(T, vh.T))
            t = vec(T)

            H = 2. * (1 + 1 / J2) * np.eye(4, 4)
            H -= 4. / J3 * (np.outer(g, f) + np.outer(f, g))
            H += 2. / J2 * (np.outer(g, r) + np.outer(r, g))
            H += 2. / J2 * (I1 - I2 / J) * HJ
            H += 2. / J3 * (3. * I2 / J - 2. * I1) * np.outer(g, g)
            H -= 4. / I1 * (1. + 1. / J) * np.outer(t, t)

        elif self.ndim == 3:

            # sigma0 = S[0,0]
            # sigma1 = S[1,1]
            # sigma2 = S[2,2]

            # sigma0 = s[0]
            # sigma1 = s[1]
            # sigma2 = s[2]

            # sqrt = np.sqrt
            # # def sqrt(x): return x

            # lambdas = [
            #     (sigma0 ** 4 * sigma1 ** 3 + sigma0 ** 3 * sigma1 ** 4 - 2 * sigma0 ** 3 * sigma1 ** 3 + sigma0 ** 3 * sigma1 - sigma0 ** 3 + sigma0 * sigma1 ** 3 - sigma1 ** 3) / (sigma0 ** 3 * sigma1 ** 3 * (sigma0 + sigma1)),
            #     (sigma1 ** 4 * sigma2 ** 3 + sigma1 ** 3 * sigma2 ** 4 - 2 * sigma1 ** 3 * sigma2 ** 3 + sigma1 ** 3 * sigma2 - sigma1 ** 3 + sigma1 * sigma2 ** 3 - sigma2 ** 3) / (sigma1 ** 3 * sigma2 ** 3 * (sigma1 + sigma2)),
            #     (sigma0 ** 4 * sigma2 ** 3 + sigma0 ** 3 * sigma2 ** 4 - 2 * sigma0 ** 3 * sigma2 ** 3 + sigma0 ** 3 * sigma2 - sigma0 ** 3 + sigma0 * sigma2 ** 3 - sigma2 ** 3) / (sigma0 ** 3 * sigma2 ** 3 * (sigma0 + sigma2)),
            #     (sigma0 ** 3 * sigma1 ** 3 - sigma0 ** 2 * sigma1 + sigma0 ** 2 - sigma0 * sigma1 ** 2 + sigma0 * sigma1 + sigma1 ** 2) / (sigma0 ** 3 * sigma1 ** 3),
            #     (sigma1 ** 3 * sigma2 ** 3 - sigma1 ** 2 * sigma2 + sigma1 ** 2 - sigma1 * sigma2 ** 2 + sigma1 * sigma2 + sigma2 ** 2) / (sigma1 ** 3 * sigma2 ** 3),
            #     (sigma0 ** 3 * sigma2 ** 3 - sigma0 ** 2 * sigma2 + sigma0 ** 2 - sigma0 * sigma2 ** 2 + sigma0 * sigma2 + sigma2 ** 2) / (sigma0 ** 3 * sigma2 ** 3),
            #     (sigma0 ** 4 - 2 * sigma0 + 3) / sigma0 ** 4,
            #     (sigma1 ** 4 - 2 * sigma1 + 3) / sigma1 ** 4,
            #     (sigma2 ** 4 - 2 * sigma2 + 3) / sigma2 ** 4
            #     ]

            # qs = [[0, 0, 0, 0, 0, 0, 1, 0, 0],
            #     [sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0, 0, 0],
            #     [0, 0, -sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0],
            #     [-sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0, 0, 0],
            #     [0, 0, 0, 0, 0, 0, 0, 1, 0],
            #     [0, -sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0, 0],
            #     [0, 0, sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0],
            #     [0, sqrt(2) / 2, 0, 0, sqrt(2) / 2, 0, 0, 0, 0],
            #     [0, 0, 0, 0, 0, 0, 0, 0, 1]
            #     ]
            # qs = np.array(qs).T

            # H = np.zeros((9,9))
            # # mm = 1./np.sqrt(2.)
            # mm=1.
            # for i in range(9):
            #     # Qi = qs[i].reshape(3,3)
            #     # Qi = mm * np.dot(u, np.dot(Qi, vh.T))
            #     # qi = vec(Qi)
            #     qi = qs[i]
            #     # print(lambdas[i])
            #     H += lambdas[i] * np.outer(qi,qi)
            #     # H += np.max([lambdas[i], 0.]) * np.outer(qi,qi)
            # # print(H)
            # return H

            def DFDF(index):
                # i = np.mod(index - 1, 3);
                # j = np.floor((index - 1) / 3);
                i = np.mod(index, 3)
                j = np.floor((index) / 3)
                i = int(i)
                j = int(j)

                DF = np.zeros((3, 3))
                DF[i, j] = 1
                return DF

            def IIC_Hessian(F):
                H = np.zeros((9, 9))
                for i in range(9):
                    DF = DFDF(i)
                    # print(DF)
                    # exit()
                    # A = 4 * (DF * F' * F + F * F' * DF + F * DF' * F);
                    A = 4 * (DF.dot(F.T.dot(F)) + F.dot(F.T.dot(DF)) +
                             F.dot(DF.T.dot(F)))
                    # print(A)
                    column = A.T.reshape(9)
                    H[:, i] = column
                return H

            def IIC_Star_Hessian(F):
                IC = np.trace(F.T.dot(F))
                H = 2 * IC * np.eye(9, 9)
                f = vec(F)
                H = H + 4 * np.outer(f, f)
                # print(H)

                IIC_H = IIC_Hessian(F)
                H = H - 2 * (IIC_H / 4.)
                return H

            # F = np.arange(9) + 1; F = F.reshape(3,3).T; F[2,2] = 50; F=F.astype(float)
            # # print(F)
            # xx = IIC_Star_Hessian(F)
            # # xx = IIC_Hessian(F)
            # # xx = IIC_Hessian(F)
            # print(xx)
            # exit()

            C = F.T.dot(F)
            IC = trace(C)
            IIC = trace(C.dot(C))
            IIStarC = 0.5 * (IC**2 - IIC)
            dIIStarC = 2 * IC * F - 2 * np.dot(F, np.dot(F.T, F))
            t = vec(dIIStarC)
            d2IIStarC = IIC_Star_Hessian(F)

            H = 2. * np.eye(9, 9)
            H -= 2. / J3 * (np.outer(g, t) + np.outer(t, g))
            H += 6. * IIStarC / J4 * np.outer(g, g)
            H += 1. / J2 * d2IIStarC
            H -= 2. * IIStarC / J3 * d2JdFdF(F)
            # print(H)

            s0 = s[0]
            s1 = s[1]
            s2 = s[2]
            # s0 = S[0,0]
            # s1 = S[1,1]
            # s2 = S[2,2]
            T1 = np.array([[0., -1., 0.], [1., 0., 0], [0., 0., 0.]])
            T1 = 1. / np.sqrt(2) * np.dot(u, np.dot(T1, vh.T))
            T2 = np.array([[0., 0., 0.], [0., 0., 1], [0., -1., 0.]])
            T2 = 1. / np.sqrt(2) * np.dot(u, np.dot(T2, vh.T))
            T3 = np.array([[0., 0., 1.], [0., 0., 0.], [-1, 0., 0.]])
            T3 = 1. / np.sqrt(2) * np.dot(u, np.dot(T3, vh.T))

            s0s1 = s0 + s1
            s0s2 = s0 + s2
            s1s2 = s1 + s2
            # if (s0s1 < 2.0):
            #     s0s1 = 2.0
            # if (s0s2 < 2.0):
            #     s0s2 = 2.0
            # if (s1s2 < 2.0):
            #     s1s2 = 2.0
            lamb1 = 2. / (s0s1)
            lamb2 = 2. / (s0s2)
            lamb3 = 2. / (s1s2)

            t1 = vec(T1)
            t2 = vec(T2)
            t3 = vec(T3)

            dRdF = (lamb1) * np.outer(t1, t1)
            dRdF += (lamb3) * np.outer(t2, t2)
            dRdF += (lamb2) * np.outer(t3, t3)
            # print(dRdF)

            IS = trace(S)
            IIS = trace(b)
            IIStarS = 0.5 * (IS * IS - IIS)

            newH = (1 + IS / J) * dRdF + (1 / J) * np.outer(r, r)
            newH = newH - (IS / J2) * (np.outer(g, r) + np.outer(r, g))
            newH = newH + (2.0 * IIStarS / J3) * np.outer(g, g)
            newH = newH - (IIStarS / J2) * HJ
            newH = newH + (1 / J2) * (np.outer(g, f) + np.outer(f, g))
            newH = newH - (1 / J) * np.eye(9, 9)
            H = H - 2.0 * newH
            H = H / 2.
            makezero(H)

            # print(H)
            # exit()

        # s = np.linalg.svd(C_Voigt)[1]
        # print(s)
        # exit()

        C_Voigt = H
        self.H_VoigtSize = H.shape[0]

        return C_Voigt
Esempio n. 17
0
def HighOrderMeshTet_SEMISTABLE(C,
                                mesh,
                                Decimals=10,
                                equally_spaced=False,
                                check_duplicates=True,
                                parallelise=False,
                                nCPU=1,
                                compute_boundary_info=True):

    from Florence.FunctionSpace import Tet
    from Florence.QuadratureRules.FeketePointsTet import FeketePointsTet
    from Florence.MeshGeneration.NodeArrangement import NodeArrangementTet

    # SWITCH OFF MULTI-PROCESSING FOR SMALLER PROBLEMS WITHOUT GIVING A MESSAGE
    Parallel = parallelise
    if (mesh.elements.shape[0] < 500) and (C < 5):
        Parallel = False
        nCPU = 1

    if not equally_spaced:
        eps = FeketePointsTet(C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        Neval = np.zeros((4, eps.shape[0]), dtype=np.float64)
        hpBases = Tet.hpNodal.hpBases
        for i in range(4, eps.shape[0]):
            Neval[:, i] = hpBases(0,
                                  eps[i, 0],
                                  eps[i, 1],
                                  eps[i, 2],
                                  Transform=1,
                                  EvalOpt=1)[0]
    else:
        from Florence.QuadratureRules.EquallySpacedPoints import EquallySpacedPointsTet
        eps = EquallySpacedPointsTet(C)
        # COMPUTE BASES FUNCTIONS AT ALL NODAL POINTS
        hpBases = Tet.hpNodal.hpBases
        Neval = np.zeros((4, eps.shape[0]), dtype=np.float64)
        for i in range(4, eps.shape[0]):
            Neval[:, i] = hpBases(0,
                                  eps[i, 0],
                                  eps[i, 1],
                                  eps[i, 2],
                                  Transform=1,
                                  EvalOpt=1,
                                  equally_spaced=True)[0]

    # THIS IS NECESSARY FOR REMOVING DUPLICATES
    makezero(Neval, tol=1e-12)

    nodeperelem = mesh.elements.shape[1]
    renodeperelem = int((C + 2.) * (C + 3.) * (C + 4.) / 6.)
    left_over_nodes = renodeperelem - nodeperelem

    reelements = -1 * np.ones(
        (mesh.elements.shape[0], renodeperelem), dtype=np.int64)
    reelements[:, :4] = mesh.elements
    # TOTAL NUMBER OF (INTERIOR+EDGE+FACE) NODES
    iesize = np.int64(C * (C - 1) * (C - 2) / 6. + 6. * C + 2 * C * (C - 1))
    repoints = np.zeros(
        (mesh.points.shape[0] + iesize * mesh.elements.shape[0], 3),
        dtype=np.float64)
    repoints[:mesh.points.shape[0], :] = mesh.points

    telements = time()

    xycoord_higher = []
    ParallelTuple1 = []
    if Parallel:
        # GET HIGHER ORDER COORDINATES - PARALLEL
        ParallelTuple1 = parmap.map(ElementLoopTet,
                                    np.arange(0, mesh.elements.shape[0]),
                                    mesh.elements,
                                    mesh.points,
                                    'tet',
                                    eps,
                                    Neval,
                                    pool=MP.Pool(processes=nCPU))

    maxNode = np.max(reelements)
    for elem in range(0, mesh.elements.shape[0]):
        # maxNode = np.max(reelements) # BIG BOTTLENECK
        if Parallel:
            xycoord_higher = ParallelTuple1[elem]
        else:
            xycoord = mesh.points[mesh.elements[elem, :], :]
            # GET HIGHER ORDER COORDINATES
            xycoord_higher = GetInteriorNodesCoordinates(
                xycoord, 'tet', elem, eps, Neval)

        # EXPAND THE ELEMENT CONNECTIVITY
        newElements = np.arange(maxNode + 1, maxNode + 1 + left_over_nodes)
        reelements[elem, 4:] = newElements
        # INSTEAD COMPUTE maxNode BY INDEXING
        maxNode = newElements[-1]

        repoints[mesh.points.shape[0] + elem * iesize:mesh.points.shape[0] +
                 (elem + 1) * iesize] = xycoord_higher[4:, :]

    if Parallel:
        del ParallelTuple1

    telements = time() - telements
    #--------------------------------------------------------------------------------------
    # NOW REMOVE DUPLICATED POINTS
    tnodes = time()

    nnode_linear = mesh.points.shape[0]
    # KEEP ZEROFY ON, OTHERWISE YOU GET STRANGE BEHVAIOUR
    # rounded_repoints = makezero(repoints[nnode_linear:,:].copy())
    rounded_repoints = repoints[nnode_linear:, :].copy()
    makezero(rounded_repoints)
    rounded_repoints = np.round(rounded_repoints, decimals=Decimals)

    _, idx_repoints, inv_repoints = unique2d(rounded_repoints,
                                             order=False,
                                             consider_sort=False,
                                             return_index=True,
                                             return_inverse=True)
    # idx_repoints.sort()
    del rounded_repoints

    idx_repoints = np.concatenate(
        (np.arange(nnode_linear), idx_repoints + nnode_linear))
    repoints = repoints[idx_repoints, :]

    unique_reelements, inv_reelements = np.unique(reelements[:, 4:],
                                                  return_inverse=True)
    unique_reelements = unique_reelements[inv_repoints]
    reelements = unique_reelements[inv_reelements]
    reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem - 4)
    reelements = np.concatenate((mesh.elements, reelements), axis=1)

    # SANITY CHECK fOR DUPLICATES
    #---------------------------------------------------------------------#
    # NOTE THAT THIS REMAPS THE ELEMENT CONNECTIVITY FOR THE WHOLE MESH
    # AND AS A RESULT THE FIRST FEW COLUMNS WOULD NO LONGER CORRESPOND TO
    # LINEAR CONNECTIVITY
    if check_duplicates:
        last_shape = repoints.shape[0]
        deci = int(Decimals) - 2
        if Decimals < 6:
            deci = Decimals
        repoints, idx_repoints, inv_repoints = remove_duplicates_2D(
            repoints, decimals=deci)
        unique_reelements, inv_reelements = np.unique(reelements,
                                                      return_inverse=True)
        unique_reelements = unique_reelements[inv_repoints]
        reelements = unique_reelements[inv_reelements]
        reelements = reelements.reshape(mesh.elements.shape[0], renodeperelem)
        if last_shape != repoints.shape[0]:
            warn(
                'Duplicated points generated in high order mesh. Lower the "Decimals". I have fixed it for now'
            )
    #---------------------------------------------------------------------#

    tnodes = time() - tnodes
    #------------------------------------------------------------------------------------------

    #------------------------------------------------------------------------------------------
    if compute_boundary_info:
        # BUILD FACES NOW
        tfaces = time()
        # GET MESH EDGES AND FACES
        fsize = int((C + 2.) * (C + 3.) / 2.)
        refaces = np.zeros((mesh.faces.shape[0], fsize),
                           dtype=mesh.faces.dtype)

        refaces = np.zeros((mesh.faces.shape[0], fsize))
        # DO NOT CHANGE THE FACES, BY RECOMPUTING THEM, AS THE LINEAR FACES CAN COME FROM
        # AN EXTERNAL MESH GENERATOR, WHOSE ORDERING MAY NOT BE THE SAME, SO JUST FIND WHICH
        # ELEMENTS CONTAIN THESE FACES
        face_to_elements = mesh.GetElementsWithBoundaryFacesTet()
        node_arranger = NodeArrangementTet(C)[0]

        refaces = reelements[face_to_elements[:, 0][:, None],
                             node_arranger[face_to_elements[:, 1], :]].astype(
                                 mesh.faces.dtype)

        tfaces = time() - tfaces
        #------------------------------------------------------------------------------------------

        #------------------------------------------------------------------------------------------
        # BUILD EDGES NOW
        tedges = time()

        # BUILD A 2D MESH
        from Florence import Mesh
        tmesh = Mesh()
        tmesh.element_type = "tri"
        tmesh.elements = refaces
        tmesh.nelem = tmesh.elements.shape[0]
        # GET BOUNDARY EDGES
        reedges = tmesh.GetEdgesTri()
        del tmesh

        tedges = time() - tedges
    #------------------------------------------------------------------------------------------

    class nmesh(object):
        # """Construct pMesh"""
        points = repoints
        elements = reelements
        edges = np.array([[], []])
        faces = np.array([[], []])
        nnode = repoints.shape[0]
        nelem = reelements.shape[0]
        info = 'tet'

    if compute_boundary_info:
        nmesh.edges = reedges
        nmesh.faces = refaces

    gc.collect()

    # print '\nHigh order meshing timing:\n\t\tElement loop:\t '+str(telements)+' seconds\n\t\tNode loop:\t\t '+str(tnodes)+\
    #  ' seconds'+'\n\t\tEdge loop:\t\t '+str(tedges)+' seconds'+\
    #  '\n\t\tFace loop:\t\t '+str(tfaces)+' seconds\n'

    return nmesh
Esempio n. 18
0
def GetBases3D(C, Quadrature, info, bases_type="nodal", equally_spaced=False, is_flattened=True):

    from Florence.Tensor import makezero
    ndim = 3

    w = Quadrature.weights
    z = Quadrature.points

    ns=[]; Basis=[]; gBasisx=[]; gBasisy=[]; gBasisz=[]
    if info=='hex':
        ns = int((C+2)**ndim)
        if is_flattened is False:
            Basis = np.zeros((ns,(z.shape[0])**ndim),dtype=np.float64)
            gBasisx = np.zeros((ns,(z.shape[0])**ndim),dtype=np.float64)
            gBasisy = np.zeros((ns,(z.shape[0])**ndim),dtype=np.float64)
            gBasisz = np.zeros((ns,(z.shape[0])**ndim),dtype=np.float64)
        else:
            Basis = np.zeros((ns,w.shape[0]),dtype=np.float64)
            gBasisx = np.zeros((ns,w.shape[0]),dtype=np.float64)
            gBasisy = np.zeros((ns,w.shape[0]),dtype=np.float64)
            gBasisz = np.zeros((ns,w.shape[0]),dtype=np.float64)
    elif info=='tet':
        p=C+1
        ns = int((p+1)*(p+2)*(p+3)/6)
        Basis = np.zeros((ns,w.shape[0]),dtype=np.float64)
        gBasisx = np.zeros((ns,w.shape[0]),dtype=np.float64)
        gBasisy = np.zeros((ns,w.shape[0]),dtype=np.float64)
        gBasisz = np.zeros((ns,w.shape[0]),dtype=np.float64)


    if info=='hex':
        if not equally_spaced:
            hpBases = Hex.LagrangeGaussLobatto
            GradhpBases = Hex.GradLagrangeGaussLobatto
        else:
            hpBases = HexES.Lagrange
            GradhpBases = HexES.GradLagrange

        if is_flattened is False:
            counter = 0
            for i in range(w.shape[0]):
                for j in range(w.shape[0]):
                    for k in range(w.shape[0]):
                        ndummy = hpBases(C,z[i],z[j],z[k])
                        dummy = GradhpBases(C,z[i],z[j],z[k])

                        Basis[:,counter] = ndummy[:,0]
                        gBasisx[:,counter] = dummy[:,0]
                        gBasisy[:,counter] = dummy[:,1]
                        gBasisz[:,counter] = dummy[:,2]
                        counter+=1
        else:
            for i in range(0,w.shape[0]):
                ndummy = hpBases(C,z[i,0],z[i,1],z[i,2])
                dummy = GradhpBases(C,z[i,0],z[i,1],z[i,2])
                Basis[:,i] = ndummy[:,0]
                gBasisx[:,i] = dummy[:,0]
                gBasisy[:,i] = dummy[:,1]
                gBasisz[:,i] = dummy[:,2]


    elif info=='tet':
        hpBases = Tet.hpNodal.hpBases
        for i in range(0,w.shape[0]):
            # Better convergence for curved meshes when Quadrature.optimal!=0
            ndummy, dummy = hpBases(C,z[i,0],z[i,1],z[i,2],Quadrature.optimal, equally_spaced=equally_spaced)
            # ndummy, dummy = Tet.hpBases(C,z[i,0],z[i,1],z[i,2])
            # makezero(ndummy)
            makezero(dummy)
            Basis[:,i] = ndummy
            gBasisx[:,i] = dummy[:,0]
            gBasisy[:,i] = dummy[:,1]
            gBasisz[:,i] = dummy[:,2]


    class Domain(object):
        """docstring for Domain"""
        Bases = Basis
        gBasesx = gBasisx
        gBasesy = gBasisy
        gBasesz = gBasisz


    return Domain