예제 #1
0
    def test_pCoordinates(self):
        NWorld = np.array([5])
        xp = util.pCoordinates(NWorld)
        self.assertTrue(np.allclose(xp.T - np.array([0., 1., 2., 3., 4., 5.])/5, 0))

        NWorld = np.array([9, 9, 9, 9])
        xp = util.pCoordinates(NWorld)
        ind = util.convertpCoordinateToIndex(NWorld, [7, 3, 6, 0])
        self.assertTrue(np.allclose(xp[ind] - np.array([7., 3., 6., 0.])/9., 0))
예제 #2
0
def invert_cq1_mapping(N, mapping):
    """Invert a y = psi(x) CQ1 mapping using the iterative method "A
    simple fixed-point approach to invert a deformation field", Chen
    et al 2008.
    """

    coords = util.pCoordinates(N)
    displace = mapping - coords

    inv_displace = np.zeros_like(displace)

    max_iter = 100
    iter = 0

    tolerance = 1e-7
    error = 1

    while iter < max_iter and error > tolerance:
        inv_displace_previous = inv_displace
        points = np.maximum(0, np.minimum(1.0, coords + inv_displace))
        inv_displace = -func.evaluateCQ1(N, displace, points)
        iter += 1
        error = np.max(np.abs(inv_displace - inv_displace_previous))

    return inv_displace + coords
예제 #3
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        x = util.pCoordinates(NFine)

        num_dots = self.num_dots
        epsilon = 0.4
        frequency = 2 * np.pi * num_dots

        displacement_unscaled = 1. / (frequency) * np.column_stack([
            0.5 * (np.sin(0.5 * frequency * x[:, 0]) + 1) *
            np.sin(frequency * x[:, 0]), 0.5 *
            (np.sin(0.5 * frequency * x[:, 1]) + 1) *
            np.sin(frequency * x[:, 1])
        ])
        point_tile_index = np.array(np.minimum(np.floor(num_dots * x),
                                               num_dots - 1),
                                    dtype=int)
        tile_scaling = epsilon * 2 * np.random.rand(num_dots, num_dots)**2
        point_scaling = tile_scaling[point_tile_index[:, 0],
                                     point_tile_index[:, 1]]

        displacement = displacement_unscaled * point_scaling[..., None]

        self.psi = discrete_mapping.MappingCQ1(NFine, x + displacement)
예제 #4
0
def d3plotter(N, s, String='FinescaleSolution', boundary=None, Blues=None, zmax=None, zmin=None, fig=None, ax=None):

    if fig is None:
        fig = plt.figure(String)
    if ax is None:
        ax = fig.add_subplot(111, projection='3d')
    
    xp = util.pCoordinates(N)
    X = xp[0:,1:].flatten()
    Y = xp[0:,:1].flatten()
    X = np.unique(X)
    Y = np.unique(Y)
    
    X, Y = np.meshgrid(X, Y)
    
    uLodFine = s.reshape(N+1)
    # Plot the surface.
    if zmin is not None:
        surf = ax.plot_surface(X, Y, uLodFine, cmap=cm.coolwarm, vmin=zmin, vmax=zmax)
    
    if boundary is not None:
        surf = ax.plot_surface(X, Y, uLodFine, cmap=cm.coolwarm, vmin=boundary[0], vmax=boundary[1])
        ax.set_zlim(boundary[0], boundary[1])
    ax.zaxis.set_major_locator(LinearLocator(10))
    if zmin is not None:
        ax.set_zlim(zmin,zmax)
    ax.axis('off')
    ax.grid(False)
    fig.subplots_adjust(left=0.00,bottom=0.00,right=1,top=1,wspace=0.2,hspace=0.2)
예제 #5
0
def d3sol(N, s, String='FinescaleSolution'):
    '''
    3d solution
    ''' 
    fig = plt.figure(String)
    ax = fig.add_subplot(111, projection='3d') 
    
    xp = util.pCoordinates(N)
    X = xp[0:,1:].flatten()
    Y = xp[0:,:1].flatten()
    X = np.unique(X)
    Y = np.unique(Y)
    
    X, Y = np.meshgrid(X, Y)
    
    uLodFine = s.reshape(N+1)

    # Plot the surface.
    surf = ax.plot_surface(X, Y, uLodFine, cmap=cm.coolwarm)
    ymin, ymax = ax.set_zlim()
    ax.set_zticks((ymin,ymax))
    ax.set_zlabel('$z$')
    ax.set_xlabel('$x$')
    ax.set_ylabel('$y$')
    ax.zaxis.set_major_locator(LinearLocator(10))
    ax.axis('off')
예제 #6
0
def d3sol(N, s, String='FinescaleSolution'):
    '''
    3d solution
    '''
    fig = plt.figure(String)
    ax = fig.add_subplot(111, projection='3d')

    xp = util.pCoordinates(N)
    X = xp[0:, 1:].flatten()
    Y = xp[0:, :1].flatten()
    X = np.unique(X)
    Y = np.unique(Y)

    X, Y = np.meshgrid(X, Y)

    uLodFine = s.reshape(N + 1)

    # Plot the surface.
    ymin, ymax = ax.set_zlim([0, 0.021])
    ax.set_zticks((ymin, ymax))
    ax.zaxis.set_major_formatter(FormatStrFormatter('%.3f'))
    ax.set_zlabel('$z$', size=16)
    ax.set_xlabel('$x$', size=16)
    ax.set_ylabel('$y$', size=16)
    # ax.view_init(50, 35)
    ax.zaxis.set_major_locator(LinearLocator(4))
    ax.tick_params(labelsize=12)
    #ax.axis('off')

    # Add a color bar which maps values to colors.
    surf = ax.plot_surface(X, Y, uLodFine, cmap=cm.hot, vmin=0, vmax=0.021)
예제 #7
0
    def test_stiffnessMatrixForConstantFullA(self):
        N = np.array([3, 4, 5], dtype='int64')
        AConstant = np.array([[3.0, 0.2, 0.1], [0.2, 2.0, 0.3],
                              [0.1, 0.3, 1.0]])
        aPatch = np.tile(AConstant, [3 * 4 * 5, 1, 1])

        ALocTensor = fem.localStiffnessTensorMatrixCoefficient(N)
        A = fem.assemblePatchMatrix(N, ALocTensor, aPatch)

        # Create the functions x1, x2 and x3
        pc = util.pCoordinates(N)
        x1 = pc[:, 0]
        x2 = pc[:, 1]
        x3 = pc[:, 2]

        # Check diagonal elements
        self.assertTrue(np.isclose(np.dot(x1, A * x1), 3.0))
        self.assertTrue(np.isclose(np.dot(x2, A * x2), 2.0))
        self.assertTrue(np.isclose(np.dot(x3, A * x3), 1.0))

        # Check off-diagonal elements
        self.assertTrue(np.isclose(np.dot(x1, A * x2), 0.2))
        self.assertTrue(np.isclose(np.dot(x2, A * x1), 0.2))
        self.assertTrue(np.isclose(np.dot(x1, A * x3), 0.1))
        self.assertTrue(np.isclose(np.dot(x3, A * x1), 0.1))
        self.assertTrue(np.isclose(np.dot(x2, A * x3), 0.3))
        self.assertTrue(np.isclose(np.dot(x3, A * x2), 0.3))
예제 #8
0
    def evaluateSolution(self, u):
        NFine = self.world.NWorldFine

        xpFine = util.pCoordinates(NFine)
        xpFine_ref = self.psi.inverse_evaluate(xpFine)

        return func.evaluateCQ1(NFine, u, xpFine_ref)
예제 #9
0
    def test_boundaryNormalDerivativeMatrixProperties(self):
        # BoundaryNormalDerivative bilinear form should map constants to 0
        NPatch = np.array([3, 4, 5])
        CLocGetter = fem.localBoundaryNormalDerivativeMatrixGetter(NPatch)
        C = fem.assemblePatchBoundaryMatrix(NPatch, CLocGetter)
        constant = np.ones(np.prod(NPatch + 1))
        self.assertTrue(np.isclose(np.linalg.norm(C * constant), 0))

        # BoundaryNormalDerivative bilinear form (a=constant) should map planes to 0
        NPatch = np.array([3, 4, 5, 6])
        CLocGetter = fem.localBoundaryNormalDerivativeMatrixGetter(NPatch)
        C = fem.assemblePatchBoundaryMatrix(NPatch, CLocGetter)

        p = util.pCoordinates(NPatch)
        pSum = np.sum(p, axis=1)
        ones = np.ones(np.prod(NPatch + 1))
        self.assertTrue(np.isclose(np.linalg.norm(np.dot(ones, C * pSum)), 0))

        # A function f with df/dx_k = 1 at x_k = 0 and df/dx_k = 0 at
        # x_k = 1 should give 1'*C*f = -d
        NPatch = np.array([5, 4, 3, 7])
        CLocGetter = fem.localBoundaryNormalDerivativeMatrixGetter(NPatch)
        C = fem.assemblePatchBoundaryMatrix(NPatch, CLocGetter)

        p = util.pCoordinates(NPatch)
        p = np.minimum(p, 0.5)
        pSum = np.sum(p, axis=1)
        ones = np.ones(np.prod(NPatch + 1))
        self.assertTrue(np.isclose(np.dot(ones, C * pSum), -4))

        # Same test as above, but with a coefficient a
        NPatch = np.array([5, 4, 3, 7])
        CLocGetter = fem.localBoundaryNormalDerivativeMatrixGetter(NPatch)

        p = util.pCoordinates(NPatch)
        p0 = p[:, 0]
        pElement = util.pCoordinates(NPatch, NPatch=NPatch - 1)
        pElement0 = pElement[:, 0]
        aPatch = 1. * (pElement0 < 0.5) + 10. * (pElement0 >= 0.5)

        C = fem.assemblePatchBoundaryMatrix(NPatch, CLocGetter, aPatch)

        ones = np.ones(np.prod(NPatch + 1))
        self.assertTrue(np.isclose(np.dot(ones, C * p0), 10 - 1))
예제 #10
0
    def test_computeElementFaceFlux_2d(self):
        NPatchCoarse = np.array([4, 6])
        NCoarseElement = np.array([10, 20])
        NPatchFine = NPatchCoarse*NCoarseElement

        NtFine = np.prod(NPatchFine)
        NpFine = np.prod(NPatchFine+1)

        aPatch = np.ones(NtFine)
        uPatch = np.ones(NpFine)
        
        fluxTF = transport.computeElementFaceFlux(NPatchCoarse, NPatchCoarse, NCoarseElement, aPatch, uPatch)
        self.assertTrue(np.all(fluxTF.shape == (24, 4)))
        self.assertTrue(np.all(fluxTF == 0))

        x = util.pCoordinates(NPatchFine)[:,0]
        y = util.pCoordinates(NPatchFine)[:,1]
        uPatch = x

        xFaceArea = 1./NPatchCoarse[1]
        fluxTF = transport.computeElementFaceFlux(NPatchCoarse, NPatchCoarse, NCoarseElement, aPatch, uPatch)
        self.assertTrue(np.allclose(fluxTF[:,0], xFaceArea) and np.allclose(fluxTF[:,1], -xFaceArea))

        uPatch = x+y

        xFaceArea = 1./NPatchCoarse[1]
        yFaceArea = 1./NPatchCoarse[0]
        fluxTF = transport.computeElementFaceFlux(NPatchCoarse, NPatchCoarse, NCoarseElement, aPatch, uPatch)
        self.assertTrue(np.allclose(fluxTF[:,0], xFaceArea) and np.allclose(fluxTF[:,1], -xFaceArea))
        self.assertTrue(np.allclose(fluxTF[:,2], yFaceArea) and np.allclose(fluxTF[:,3], -yFaceArea))

        aPatch = 10*aPatch
        fluxTF = transport.computeElementFaceFlux(NPatchCoarse, NPatchCoarse, NCoarseElement, aPatch, uPatch)
        self.assertTrue(np.allclose(fluxTF[:,0], 10*xFaceArea) and np.allclose(fluxTF[:,1], -10*xFaceArea))
        self.assertTrue(np.allclose(fluxTF[:,2], 10*yFaceArea) and np.allclose(fluxTF[:,3], -10*yFaceArea))

        aPatch = np.ones(NtFine)
        NWorldCoarse = np.array(NPatchCoarse)
        NWorldCoarse[0] = 10*NWorldCoarse[0]
        fluxTF = transport.computeElementFaceFlux(NWorldCoarse, NPatchCoarse, NCoarseElement, aPatch, uPatch)
        self.assertTrue(np.allclose(fluxTF[:,0], 10*xFaceArea) and np.allclose(fluxTF[:,1], -10*xFaceArea))
        self.assertTrue(np.allclose(fluxTF[:,2], 0.1*yFaceArea) and np.allclose(fluxTF[:,3], -0.1*yFaceArea))
예제 #11
0
    def test_smooth_1d(self):
        N = np.array([1000])
        x = util.pCoordinates(N)

        e = np.exp(1)
        mapping = (np.exp(x)-1)/(e-1)
        
        inv_mapping = discrete_mapping.invert_cq1_mapping(N, mapping)
        inv_mapping_should_be = np.log((e-1)*x+1)

        self.assertTrue(np.allclose(inv_mapping, inv_mapping_should_be, atol=1e-3))
예제 #12
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        xpFine = util.pCoordinates(NFine)

        forward_mapping = np.stack([xpFine[:, 0], xpFine[:, 1]], axis=1)

        xpFine_shaped = xpFine.reshape(fine + 1, fine + 1, 2)

        for i in [1, 3]:
            middle = int((fine + 1) * (i / 4))
            intervall = int((fine + 1) / 8)

            left_2 = middle - int(intervall)
            right_2 = middle + int(intervall)

            left, right = left_2, right_2

            # print(fine + 1, left, right)

            part_x = xpFine_shaped[left:right, left_2:right_2, 0]
            part_y = xpFine_shaped[left:right, left_2:right_2, 1]
            left_margin_x = np.min(part_x)
            right_margin_x = np.max(part_x)
            left_margin_y = np.min(part_y)
            right_margin_y = np.max(part_y)

            # print(left_margin_x, right_margin_x, left_margin_y, right_margin_y)

            epsilon = self.bending_factor / (
                right_margin_y - left_margin_y
            )  # why does this have to be so large???

            forward_mapping_partial = np.stack([
                xpFine_shaped[left:right, left_2:right_2, 0] + epsilon *
                (xpFine_shaped[left:right, left_2:right_2, 0] - left_margin_x)
                * (right_margin_x -
                   xpFine_shaped[left:right, left_2:right_2, 0]) *
                (xpFine_shaped[left:right, left_2:right_2, 1] - left_margin_y)
                * (right_margin_y -
                   xpFine_shaped[left:right, left_2:right_2, 1]),
                xpFine_shaped[left:right, left_2:right_2, 1]
            ],
                                               axis=2)

            forward_mapping_shaped = forward_mapping.reshape(
                fine + 1, fine + 1, 2)
            forward_mapping_shaped[left:right,
                                   left_2:right_2, :] = forward_mapping_partial

        forward_mapping = forward_mapping_shaped.reshape((fine + 1)**2, 2)

        self.psi = discrete_mapping.MappingCQ1(NFine, forward_mapping)
예제 #13
0
    def test_smooth_2d(self):
        N = np.array([100, 100])
        x = util.pCoordinates(N)

        e = np.exp(1)
        mapping = (np.exp([x[:,0] + 0.1*x[:,0]*(1-x[:,0])*x[:,1]*(1-x[:,1]),
                           x[:,1] + 0.1*x[:,1]*(1-x[:,1])*x[:,0]*(1-x[:,0])])-1)/(e-1)

        mapping = np.transpose(mapping)
        
        inv_mapping = discrete_mapping.invert_cq1_mapping(N, mapping)
        inv_inv_mapping = discrete_mapping.invert_cq1_mapping(N, inv_mapping)

        self.assertTrue(np.allclose(mapping, inv_inv_mapping, atol=1e-4))
예제 #14
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]

        xpFine = util.pCoordinates(NFine)

        forward_mapping = np.stack([xpFine[:, 0], xpFine[:, 1]], axis=1)

        xpFine_shaped = xpFine.reshape(fine + 1, fine + 1, 2)

        left = int((fine + 1) * self.area[0])
        right = int((fine + 1) * self.area[1])

        # TODO: enable other left_2 and right_2
        left_2, right_2 = left, right

        print('left_right ', left, right)

        part_x = xpFine_shaped[left:right, left_2:right_2, 0]
        part_y = xpFine_shaped[left:right, left_2:right_2, 1]
        left_margin_x = np.min(part_x)
        right_margin_x = np.max(part_x)
        left_margin_y = np.min(part_y)
        right_margin_y = np.max(part_y)

        print(left_margin_x, right_margin_x, left_margin_y, right_margin_y)

        epsilon = self.bending_factor / (
            right_margin_y - left_margin_y
        )  # why does this have to be so large???

        forward_mapping_partial = np.stack([
            xpFine_shaped[left:right, left_2:right_2, 0] + epsilon *
            (xpFine_shaped[left:right, left_2:right_2, 0] - left_margin_x) *
            (right_margin_x - xpFine_shaped[left:right, left_2:right_2, 0]) *
            (xpFine_shaped[left:right, left_2:right_2, 1] - left_margin_y) *
            (right_margin_y - xpFine_shaped[left:right, left_2:right_2, 1]),
            xpFine_shaped[left:right, left_2:right_2, 1]
        ],
                                           axis=2)

        forward_mapping_shaped = forward_mapping.reshape(fine + 1, fine + 1, 2)
        forward_mapping_shaped[left:right,
                               left_2:right_2, :] = forward_mapping_partial

        forward_mapping = forward_mapping_shaped.reshape((fine + 1)**2, 2)

        self.psi = discrete_mapping.MappingCQ1(NFine, forward_mapping)
예제 #15
0
    def test_boundarypIndexMap(self):
        N = np.array([3,4,5])
        Np = np.prod(N+1)
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N) == shouldBe))
                     
        boundaryMap = np.array([[True, False],
                                [True, True],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        coords = util.pCoordinates(N)
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] == 1,
                                                   np.logical_and(coords[:,1] != 0,
                                                   np.logical_and(coords[:,1] != 1,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))
        
        boundaryMap = np.array([[True, True],
                                [False, True],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 0,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))

        boundaryMap = np.array([[True, True],
                                [False, False],
                                [True, True]])
        shouldBe = np.setdiff1d(np.arange(Np), util.interiorpIndexMap(N))
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 0,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        shouldBe = np.setdiff1d(shouldBe, np.where(np.logical_and(coords[:,0] != 0,
                                                   np.logical_and(coords[:,0] != 1,
                                                   np.logical_and(coords[:,1] == 1,
                                                   np.logical_and(coords[:,2] != 0,
                                                                  coords[:,2] != 1)))))[0])
        self.assertTrue(np.all(util.boundarypIndexMapLarge(N, boundaryMap) == shouldBe))
예제 #16
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        x = util.pCoordinates(NFine)

        x0 = np.array([0.5, 0.5])

        r = np.linalg.norm((x - x0), axis=1)
        r_min = self.r_min
        r_bounded = np.maximum(r, r_min) / r_min

        tapering = np.prod(np.sin(np.pi * x), axis=1)

        displacement = np.column_stack([
            tapering * self.displacement_factor * (r_bounded)**-2,
            tapering * self.displacement_factor * (r_bounded)**-2
        ])

        self.psi = discrete_mapping.MappingCQ1(NFine, x + displacement)
예제 #17
0
    def test_stiffnessMatrixForVaryingDiagonalA(self):
        N = np.array([3, 4, 5], dtype='int64')
        AConstant1 = np.array([[1.0, 0, 0], [0, 2.0, 0], [0, 0, 1.0]])
        AConstant2 = np.array([[1.0, 0, 0], [0, 7.0, 0], [0, 0, 1.0]])
        aPatchCube = np.tile(AConstant1, [3, 4, 5, 1, 1])
        aPatchCube[:, :2, :, :, :] = AConstant2
        aPatch = np.reshape(aPatchCube, [3 * 4 * 5, 3, 3])

        ALocTensor = fem.localStiffnessTensorMatrixCoefficient(N)
        A = fem.assemblePatchMatrix(N, ALocTensor, aPatch)

        # Create the functions x1, x2 and x3
        pc = util.pCoordinates(N)
        x1 = pc[:, 0]
        x2 = pc[:, 1]
        x3 = pc[:, 2]

        self.assertTrue(np.isclose(np.dot(x1, A * x1), 1.0))
        self.assertTrue(np.isclose(np.dot(x2, A * x2), 0.5 * (2. + 7.)))
        self.assertTrue(np.isclose(np.dot(x3, A * x3), 1.0))
예제 #18
0
    def computeTransformation(self, aFine, f_ref):
        assert (len(aFine) == np.prod(self.world.NWorldFine))
        assert (len(f_ref) == np.prod(self.world.NWorldFine + 1))
        assert (self.psi)
        psi = self.psi

        NFine = self.world.NWorldFine
        xtFine = util.tCoordinates(NFine)

        a_trans = np.einsum('tij, t, tkj, t -> tik', psi.Jinv(xtFine), aFine,
                            psi.Jinv(xtFine), psi.detJ(xtFine))

        xpFine = util.pCoordinates(NFine)
        xpFine_pert = self.psi.evaluate(xpFine)

        f_trans = func.evaluateCQ1(NFine, f_ref, xpFine_pert)

        f_trans = np.einsum('t, t -> t', f_trans, psi.detJ(xpFine_pert))

        return a_trans, f_trans
예제 #19
0
    def computePerturbation(self, aFine, f_ref):
        assert (self.psi)
        assert (len(aFine) == np.prod(self.world.NWorldFine))

        NFine = self.world.NWorldFine

        # Elements
        xtFine = util.tCoordinates(NFine)
        xtFine_ref = self.psi.inverse_evaluate(xtFine)
        xtFine_pert = self.psi.evaluate(xtFine_ref)

        # Nodes
        xpFine = util.pCoordinates(NFine)
        xpFine_ref = self.psi.inverse_evaluate(xpFine)
        xpFine_pert = self.psi.evaluate(xpFine_ref)

        self.checkInvertible(xpFine_pert, xpFine)

        aFine_pert = func.evaluateDQ0(NFine, aFine, xtFine_ref)
        # f_pert = func.evaluateCQ1(NFine, f_ref, xpFine_ref)
        return aFine_pert, f_ref
예제 #20
0
def d3solextra(N, s, fig, ax, ymin, ymax):
    '''
    function for 2d fem example
    '''

    xp = util.pCoordinates(N)
    X = xp[0:, 1:].flatten()
    Y = xp[0:, :1].flatten()
    X = np.unique(X)
    Y = np.unique(Y)

    X, Y = np.meshgrid(X, Y)

    uLodFine = s.reshape(N + 1)

    # Plot the surface.
    surf = ax.plot_surface(X, Y, uLodFine, cmap=cm.jet)
    ymin, ymax = ax.set_zlim()
    ax.set_zlim(ymin, ymax)
    ax.set_zlabel('$z$')
    ax.set_xlabel('$x$')
    ax.set_ylabel('$y$')
    ax.zaxis.set_major_locator(LinearLocator(10))
    ax.axis('off')
예제 #21
0
import matplotlib.pyplot as plt
from gridlod import util, fem, coef, interp
from gridlod.world import World
import lod_wave

# fine mesh parameters
fine = 1024
NFine = np.array([fine])
NpFine = np.prod(NFine + 1)
boundaryConditions = np.array([[0, 0]])
world = World(NFine, NFine // NFine, boundaryConditions)
NWorldFine = world.NWorldCoarse * world.NCoarseElement

# fine grid elements and nodes
xt = util.tCoordinates(NFine).flatten()
xp = util.pCoordinates(NFine).flatten()

# time step parameters
tau = 0.1
numTimeSteps = 10

# ms coefficients
epsA = 2 ** (-4)
epsB = 2 ** (-6)
aFine = (2 - np.sin(2 * np.pi * xt / epsA)) ** (-1)
bFine = (2 - np.cos(2 * np.pi * xt / epsB)) ** (-1)

k_0 = np.inf
k_1 = k_0
N = 16
예제 #22
0
    def test_1d(self):
        # Example from Peterseim, Variational Multiscale Stabilization and the Exponential Decay of correctors, p. 2
        # Two modifications: A with minus and u(here) = 1/4*u(paper).
        NFine = np.array([3200])
        NpFine = np.prod(NFine + 1)
        NList = [10, 20, 40, 80, 160]
        epsilon = 1024. / NFine
        epsilon = 1. / 320
        k = 2

        pi = np.pi

        xt = util.tCoordinates(NFine).flatten()
        xp = util.pCoordinates(NFine).flatten()
        #aFine = (2 + np.cos(2*pi*xt/epsilon))**(-1)
        aFine = (2 - np.cos(2 * pi * xt / epsilon))**(-1)

        uSol = 4 * (xp - xp**2) - 4 * epsilon * (
            1 / (4 * pi) * np.sin(2 * pi * xp / epsilon) - 1 /
            (2 * pi) * xp * np.sin(2 * pi * xp / epsilon) - epsilon /
            (4 * pi**2) * np.cos(2 * pi * xp / epsilon) + epsilon /
            (4 * pi**2))

        uSol = uSol / 4

        previousErrorCoarse = np.inf
        previousErrorFine = np.inf

        for N in NList:
            NWorldCoarse = np.array([N])
            NCoarseElement = NFine / NWorldCoarse
            boundaryConditions = np.array([[0, 0]])
            world = World(NWorldCoarse, NCoarseElement, boundaryConditions)

            xpCoarse = util.pCoordinates(NWorldCoarse).flatten()

            NpCoarse = np.prod(NWorldCoarse + 1)

            IPatchGenerator = lambda i, N: interp.L2ProjectionPatchMatrix(
                i, N, NWorldCoarse, NCoarseElement, boundaryConditions)
            aCoef = coef.coefficientFine(NWorldCoarse, NCoarseElement, aFine)

            pglod = pg.PetrovGalerkinLOD(world, k, IPatchGenerator, 0)
            pglod.updateCorrectors(aCoef, clearFineQuantities=False)

            KFull = pglod.assembleMsStiffnessMatrix()
            MFull = fem.assemblePatchMatrix(NWorldCoarse, world.MLocCoarse)

            free = util.interiorpIndexMap(NWorldCoarse)

            f = np.ones(NpCoarse)
            bFull = MFull * f

            KFree = KFull[free][:, free]
            bFree = bFull[free]

            xFree = sparse.linalg.spsolve(KFree, bFree)

            basis = fem.assembleProlongationMatrix(NWorldCoarse,
                                                   NCoarseElement)
            basisCorrectors = pglod.assembleBasisCorrectors()
            modifiedBasis = basis - basisCorrectors
            xFull = np.zeros(NpCoarse)
            xFull[free] = xFree
            uLodCoarse = basis * xFull
            uLodFine = modifiedBasis * xFull

            AFine = fem.assemblePatchMatrix(NFine, world.ALocFine, aFine)
            MFine = fem.assemblePatchMatrix(NFine, world.MLocFine)

            newErrorCoarse = np.sqrt(
                np.dot(uSol - uLodCoarse, MFine * (uSol - uLodCoarse)))
            newErrorFine = np.sqrt(
                np.dot(uSol - uLodFine, AFine * (uSol - uLodFine)))

            self.assertTrue(newErrorCoarse < previousErrorCoarse)
            self.assertTrue(newErrorFine < previousErrorFine)
예제 #23
0
 def computeFunctions():
     pc = util.pCoordinates(NFine)
     x1 = pc[:,0]
     x2 = pc[:,1]
     return [x1, 2*x2]
예제 #24
0
aFine_ref_shaped = CoefClass.SpecificMove(Number=np.arange(0, 10),
                                          steps=4,
                                          Right=1)
aFine_ref = aFine_ref_shaped.flatten()
number_of_channels = len(CoefClass.ShapeRemember)

# Discrete mapping
Nmapping = np.array([int(fine), int(fine)])

size_of_an_element = 1. / fine
walk_with_perturbation = size_of_an_element

channels_position_from_zero = space
channels_end_from_zero = channels_position_from_zero + thick

xpFine = util.pCoordinates(NFine)
xtFine = util.tCoordinates(NFine)

NWorldCoarse = np.array([N, N])
boundaryConditions = np.array([[0, 0], [0, 0]])

NCoarseElement = NFine // NWorldCoarse
world = World(NWorldCoarse, NCoarseElement, boundaryConditions)
every_psi_was_valid = []
k = 3

#I want to know the exact places of the channels
ref_array = aFine_ref_shaped[0]


def create_psi_function():
예제 #25
0
 def computeFunctions():
     pc = util.pCoordinates(world.NWorldFine)
     x1 = pc[:,0]
     x2 = pc[:,1]
     return [x1]
예제 #26
0
    def test_pgtransport(self):
        NWorldCoarse = np.array([16, 16])
        NCoarseElement = np.array([8, 8])
        NWorldFine = NWorldCoarse * NCoarseElement
        boundaryConditions = np.array([[1, 1], [0, 0]])

        d = 2

        world = World(NWorldCoarse, NCoarseElement, boundaryConditions)

        # Load coefficient
        aLogBase = np.loadtxt(
            os.path.dirname(os.path.realpath(__file__)) +
            '/data/randomfield64x64')
        #aBase = np.loadtxt(os.path.dirname(os.path.realpath(__file__)) + '/data/upperness_x.txt')
        #aBase = aBase[:60*220]
        #aLogBase = np.random.rand(128*128)
        aBase = np.exp(3 * aLogBase)

        drawCoefficient(NWorldFine, aBase)
        plt.title('a')

        # Compute coordinates
        coordsFine = util.pCoordinates(NWorldFine)
        xFine = coordsFine[:, 0]
        yFine = coordsFine[:, 1]

        # Compute fixed and free dofs
        allDofs = np.arange(world.NpFine)
        fixed = util.boundarypIndexMap(NWorldFine, boundaryConditions == 0)
        free = np.setdiff1d(allDofs, fixed)

        # Compute matrices
        AFull = fem.assemblePatchMatrix(NWorldFine, world.ALocFine, aBase)
        A = AFull[free][:, free]

        # Compute rhs
        gFine = 1 - yFine
        bFull = -AFull * gFine
        b = bFull[free]

        # Solve fine system
        u0Free = sparse.linalg.spsolve(A, b)
        u0Full = np.zeros(world.NpFine)
        u0Full[free] = u0Free

        uFull = u0Full + gFine

        ## First, compute flux on fine mesh
        def computeAvgVelocitiesTF(NFluxElement):
            fluxWorld = World(NWorldFine / NFluxElement, NFluxElement,
                              boundaryConditions)

            if True:
                avgFluxTF = transport.computeHarmonicMeanFaceFlux(
                    fluxWorld.NWorldCoarse, fluxWorld.NWorldCoarse,
                    NFluxElement, aBase, uFull)
                avgFluxTF = transport.computeAverageFaceFlux(
                    fluxWorld.NWorldCoarse, avgFluxTF)
                conservativeFluxTF = transport.computeConservativeFlux(
                    fluxWorld, avgFluxTF)

            if False:
                avgFluxTF = transport.computeElementFaceFlux(
                    fluxWorld.NWorldCoarse, fluxWorld.NWorldCoarse,
                    NFluxElement, aBase, uFull)
                avgFluxTF = transport.computeAverageFaceFlux(
                    fluxWorld.NWorldCoarse, avgFluxTF)

            return avgFluxTF, conservativeFluxTF

        avgFluxTF, conservativeFluxTF = computeAvgVelocitiesTF(NCoarseElement)
        avgFluxtf, conservativeFluxtf = computeAvgVelocitiesTF(
            np.ones_like(NCoarseElement))

        def fractionalFlow(s):
            return s**3

        boundarys = np.array([[0, 0], [1, 0]])

        sT = np.zeros(world.NtCoarse)
        st = np.zeros(world.NtFine)

        nTime = 1e5
        endTime = 1
        dTime = endTime / float(nTime)
        volt = np.prod(1. / world.NWorldFine)
        volT = np.prod(1. / world.NWorldCoarse)

        plt.figure()
        h1 = plt.gcf().number
        plt.figure()
        h2 = plt.gcf().number
        plt.figure()
        h3 = plt.gcf().number

        for timeStep in np.arange(nTime):

            def computeElementNetFluxT(NFluxElement, avgFluxTF, sT):
                fluxWorld = World(NWorldFine / NFluxElement, NFluxElement,
                                  boundaryConditions)
                netFluxT = transport.computeElementNetFlux(
                    fluxWorld, avgFluxTF, sT, boundarys, fractionalFlow)
                return netFluxT

            netFluxT = computeElementNetFluxT(NCoarseElement,
                                              conservativeFluxTF, sT)
            netFluxt = computeElementNetFluxT(np.ones_like(NCoarseElement),
                                              conservativeFluxtf, st)

            sT = sT + dTime / volT * netFluxT
            #sT[sT > 1] = 1.
            #sT[sT < 0] = 0.

            st = st + dTime / volt * netFluxt
            #st[st > 1] = 1.
            #st[st < 0] = 0.

            if timeStep % 1000 == 0 or timeStep == nTime - 1:
                plt.figure(h1)
                drawSaturation(NWorldCoarse, sT)
                plt.title('sT')
                plt.gcf().canvas.draw()

                plt.figure(h2)
                drawSaturation(NWorldFine, st)
                plt.title('st')
                plt.gcf().canvas.draw()

                plt.figure(h3)
                stProjected = projectSaturation(NWorldCoarse, NCoarseElement,
                                                st)
                drawSaturation(NWorldCoarse, stProjected)
                plt.title('st projected')
                plt.gcf().canvas.draw()

                print np.sqrt(np.mean((stProjected - sT)**2))

                plt.pause(0.0001)
        plt.show()
예제 #27
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        xpFine = util.pCoordinates(NFine)

        epsilonT = []

        forward_mapping = np.stack([xpFine[:, 0], xpFine[:, 1]], axis=1)

        xpFine_shaped = xpFine.reshape(fine + 1, fine + 1, 2)
        left, right = 0, fine + 1

        for c in range(self.number_of_channels):
            count = 0
            for i in range(np.size(self.ref_array)):
                if self.ref_array[i] == 1:
                    count += 1
                if count == (c + 1) * self.thick:
                    begin = i + 1 - self.space // 2
                    end = i + 1 + self.thick + self.space // 2
                    break
            print(begin, end)
            left_2, right_2 = begin, end
            if c == 3:
                epsilon = 25
            # elif c == 4:
            #    epsilon = -25
            # elif c % 2 == 0:
            #    epsilon = 0
            else:
                epsilon = np.random.uniform(-10, 10)

            part_x = xpFine_shaped[left:right, left_2:right_2, 0]
            part_y = xpFine_shaped[left:right, left_2:right_2, 1]
            left_margin_x = np.min(part_x)
            right_margin_x = np.max(part_x)
            left_margin_y = np.min(part_y)
            right_margin_y = np.max(part_y)

            print(left_margin_x, right_margin_x, left_margin_y, right_margin_y)

            forward_mapping_partial = np.stack([
                xpFine_shaped[left:right, left_2:right_2, 0] + epsilon *
                (xpFine_shaped[left:right, left_2:right_2, 0] - left_margin_x)
                * (right_margin_x -
                   xpFine_shaped[left:right, left_2:right_2, 0]) *
                (xpFine_shaped[left:right, left_2:right_2, 1] - left_margin_y)
                * (right_margin_y -
                   xpFine_shaped[left:right, left_2:right_2, 1]),
                xpFine_shaped[left:right, left_2:right_2, 1]
            ],
                                               axis=2)

            forward_mapping_shaped = forward_mapping.reshape(
                fine + 1, fine + 1, 2)
            forward_mapping_shaped[left:right,
                                   left_2:right_2, :] = forward_mapping_partial

            epsilonT.append(epsilon)

        forward_mapping = forward_mapping_shaped.reshape((fine + 1)**2, 2)

        print('Those are the results of the shift epsilon', epsilonT)

        self.psi = discrete_mapping.MappingCQ1(NFine, forward_mapping)
예제 #28
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        xpFine = util.pCoordinates(NFine)

        Nmapping = np.array([int(fine), int(fine)])

        size_of_an_element = 1. / fine
        print('the size of a fine element is {}'.format(size_of_an_element))
        walk_with_perturbation = size_of_an_element

        epsilonT = []
        cq1 = np.zeros((int(fine) + 1, int(fine) + 1))
        random.seed(20)
        cs = np.random.randint(0, 2, self.number_of_channels)
        cs = [c * random.sample([-1, 1], 1)[0] for c in cs]

        ## or manually
        cs[2] = 0
        cs[3] = -1
        cs[4] = 0
        cs[5] = 0

        print(cs)

        last_value = 0
        for i, c in enumerate(cs):
            platform = self.space // 2 + 2 * self.thick
            begin = platform // 2 + i * (self.space + self.thick)
            end = begin + self.space - platform + self.thick

            epsilon = c * walk_with_perturbation
            epsilonT.append(epsilon)
            walk = epsilon - last_value

            constant_length = platform + self.thick
            increasing_length = end - begin

            for i in range(increasing_length):
                cq1[:, begin +
                    i] = last_value + (i + 1) / increasing_length * walk

            for i in range(constant_length):
                cq1[:, begin + increasing_length + i] = epsilon

            last_value = epsilon

        # ending
        begin += self.space + self.thick
        end = begin + self.space - platform + self.thick
        epsilon = 0
        walk = epsilon - last_value
        increasing_length = end - begin
        for i in range(increasing_length):
            cq1[:, begin + i] = last_value + (i + 1) / increasing_length * walk

        if self.plot_mapping:
            plt.plot(np.arange(0, fine + 1),
                     cq1[self.space, :],
                     label='$id(x) - \psi(x)$')
            plt.title('Domain mapping')
            plt.legend()
            plt.show()

        print('These are the results of the shift epsilon', epsilonT)
        cq1 = cq1.flatten()

        alpha = 1.

        for_mapping = np.stack(
            (xpFine[:, 0] + alpha * func.evaluateCQ1(Nmapping, cq1, xpFine),
             xpFine[:, 1]),
            axis=1)
        self.psi = discrete_mapping.MappingCQ1(NFine, for_mapping)
예제 #29
0
#two examples of the offline coeffs
Nepsilon = np.array([64, 64])
NFine = np.array([256, 256])
NCoarse = np.array([32, 32])
k = 2
alpha = 0.1
beta = 1.
incl_bl = np.array([0.25, 0.25])
incl_tr = np.array([0.75, 0.75])
NCoarseElement = NFine // NCoarse
world = World(NCoarse, NCoarseElement, None)
middle = world.NWorldCoarse[1] // 2 * world.NWorldCoarse[
    0] + world.NWorldCoarse[0] // 2
patch = lod_periodic.PatchPeriodic(world, k, middle)
xpFine = util.pCoordinates(world.NWorldCoarse, patch.iPatchWorldCoarse,
                           patch.NPatchCoarse)

aRefList_rand = build_coefficient.build_checkerboardbasis(
    patch.NPatchCoarse, Nepsilon // NCoarse, world.NCoarseElement, alpha, beta)

fig = plt.figure()
for ii in range(4):
    ax = fig.add_subplot(2, 2, ii + 1)
    apertGrid = aRefList_rand[-1 + ii].reshape(patch.NPatchFine, order='C')
    im = ax.imshow(apertGrid,
                   origin='lower_left',
                   extent=(xpFine[:, 0].min(), xpFine[:, 0].max(),
                           xpFine[:, 1].min(), xpFine[:, 1].max()),
                   cmap='Greys')
plt.show()
예제 #30
0
    def create(self):
        NFine = self.world.NWorldFine
        fine = NFine[0]
        xpFine = util.pCoordinates(NFine)

        number_of_perturbed_channels = 4

        now = 0
        count = 0
        for i in range(np.size(self.ref_array)):
            if self.ref_array[i] == 1:
                count += 1
            if count == 8 * self.thick:  # at the 8ths shape (which is the last dot in one line, the cq starts)
                begin = i + 1
                break
        count = 0
        for i in range(np.size(self.ref_array)):
            if self.ref_array[i] == 1:
                count += 1
            if count == 13 * self.thick - 3:  # it ends after the last channel
                end = i
                break

        # Discrete mapping
        Nmapping = np.array([int(fine), int(fine)])
        cq1 = np.zeros((int(fine) + 1, int(fine) + 1))

        # I only want to perturb on the fine mesh.
        size_of_an_element = 1. / fine
        walk_with_perturbation = size_of_an_element

        channels_position_from_zero = self.space
        channels_end_from_zero = channels_position_from_zero + self.thick

        # The next only have the purpose to make the psi invertible.
        increasing_length = (end - begin) // (number_of_perturbed_channels +
                                              1) - self.thick - 2
        constant_length = (end - begin) - increasing_length * 2
        maximum_walk = (increasing_length - 6) * walk_with_perturbation
        walk_with_perturbation = maximum_walk
        for i in range(increasing_length):
            cq1[:, begin + 1 +
                i] = (i + 1) / increasing_length * walk_with_perturbation
            cq1[:, begin + increasing_length + i +
                constant_length] = walk_with_perturbation - (
                    i + 1) / increasing_length * walk_with_perturbation
        for i in range(constant_length):
            cq1[:, begin + increasing_length + i] = walk_with_perturbation

        # Check what purtubation I have
        if self.plot_mapping:
            plt.figure('DomainMapping')
            plt.plot(np.arange(0, fine + 1),
                     cq1[self.space, :],
                     label='$id(x) - \psi(x)$')
            plt.title('Domain mapping')
            plt.legend()

        cq1 = cq1.flatten()

        xpFine = util.pCoordinates(NFine)

        alpha = 1.

        for_mapping = np.stack(
            (xpFine[:, 0] + alpha * func.evaluateCQ1(Nmapping, cq1, xpFine),
             xpFine[:, 1]),
            axis=1)
        self.psi = discrete_mapping.MappingCQ1(NFine, for_mapping)