Пример #1
0
print()

KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT)
RFull = pglod.assemblePatchFunction(world, patchT, RmsiT)
MFull = fem.assemblePatchMatrix(world.NWorldFine, world.MLocFine)

Rf = pglod.assemblePatchFunction(world, patchT, correctorRhsT)

basis = fem.assembleProlongationMatrix(world.NWorldCoarse, world.NCoarseElement)

bFull = basis.T * MFull * f_trans - RFull

basisCorrectors = pglod.assembleBasisCorrectors(world, patchT, correctorsListT)
modifiedBasis = basis - basisCorrectors

uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions)

uLodFine = modifiedBasis * uFull
uLodFine += Rf

u_best_LOD = uLodFine

energy_norm = np.sqrt(np.dot(u_best_LOD, AFine_trans * u_best_LOD))
energy_error = np.sqrt(np.dot((uFineFull_trans - u_best_LOD), AFine_trans * (uFineFull_trans - u_best_LOD)))
print("Energy norm {}, error {}, rel. error {}".format(energy_norm, energy_error, energy_error/energy_norm))


# Use mapper to distribute computations (mapper could be the 'map' built-in or e.g. an ipyparallel map)
print('computing correctors',  end='', flush=True)
patchT, correctorsListT, KmsijT, csiT = zip(*map(computeKmsij, range(world.NtCoarse)))
print()
Пример #2
0
def Monte_Carlo_simulation():
    print('Computing Monte Carlo step')

    global aFine_ref
    global aFine_trans
    global aFine_pert
    global k
    global KmsijT
    global correctorsListT

    aFine_ref = aFine_ref_shaped.flatten()
    psi, cq1 = create_psi_function()

    # plt.figure('domain mapping')
    # plt.plot(np.arange(0, fine + 1), cq1[0, :], label='$id(x) - \psi(x)$')
    # plt.plot(np.arange(0, fine), ref_array * 0.01)
    # plt.title('Domain mapping')
    # plt.legend()

    xpFine_pert = psi.evaluate(xpFine)
    xpFine_ref = psi.inverse_evaluate(xpFine)

    xtFine_pert = psi.evaluate(xtFine)
    xtFine_ref = psi.inverse_evaluate(xtFine)

    aFine_pert = func.evaluateDQ0(NFine, aFine_ref, xtFine_ref)
    aBack_ref = func.evaluateDQ0(NFine, aFine_pert, xtFine_pert)

    print('Psi is invertible if this is zero: {}'.format(
        np.linalg.norm(aBack_ref - aFine_ref)))
    every_psi_was_valid.append(np.linalg.norm(aBack_ref - aFine_ref))
    #aFine_trans is the transformed perturbed reference coefficient
    aFine_trans = np.einsum('tji, t, tkj, t -> tik', psi.Jinv(xtFine),
                            aFine_ref, psi.Jinv(xtFine), psi.detJ(xtFine))

    f_pert = np.ones(np.prod(NFine + 1))
    f_ref = func.evaluateCQ1(NFine, f_pert, xpFine_pert)
    f_trans = np.einsum('t, t -> t', f_ref, psi.detJ(xpFine))

    uFineFull_pert, AFine_pert, MFine = femsolver.solveFine(
        world, aFine_pert, f_pert, None, boundaryConditions)
    uFineFull_trans, AFine_trans, _ = femsolver.solveFine(
        world, aFine_trans, f_trans, None, boundaryConditions)

    uFineFull_trans_pert = func.evaluateCQ1(NFine, uFineFull_trans, xpFine_ref)

    energy_norm = np.sqrt(np.dot(uFineFull_pert, AFine_pert * uFineFull_pert))
    energy_error = np.sqrt(
        np.dot((uFineFull_trans_pert - uFineFull_pert),
               AFine_pert * (uFineFull_trans_pert - uFineFull_pert)))
    print("Energy norm {}, error {}, rel. error {}".format(
        energy_norm, energy_error, energy_error / energy_norm))

    Aeye = np.tile(np.eye(2), [np.prod(NFine), 1, 1])
    aFine_ref = np.einsum('tji, t-> tji', Aeye, aFine_ref)

    print('compute domain mapping error indicators')
    epsFine, epsCoarse = zip(*map(computeIndicators, range(world.NtCoarse)))

    print('apply tolerance')
    Elements_to_be_updated = []
    TOL = 0.1
    for i in range(world.NtCoarse):
        if epsFine[i] >= TOL:
            Elements_to_be_updated.append(i)

    print('.... to be updated for domain mapping: {}%'.format(
        np.size(Elements_to_be_updated) / np.size(epsFine) * 100))

    print('update correctors')
    if np.size(Elements_to_be_updated) == 0:
        correctorsListTNew, KmsijTNew = correctorsListT, KmsijT
    else:
        patchT_irrelevant, correctorsListTNew, KmsijTNew, csiTNew = zip(
            *map(UpdateCorrectors, Elements_to_be_updated))

    KmsijT_list = list(KmsijT)
    correctorsListT_list = list(correctorsListT)
    i = 0
    for T in Elements_to_be_updated:
        KmsijT_list[T] = KmsijTNew[i]
        correctorsListT_list[T] = correctorsListTNew[i]
        i += 1

    KmsijT = tuple(KmsijT_list)
    correctorsListT = tuple(correctorsListT_list)

    print('solve the system')
    KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT)

    MFull = fem.assemblePatchMatrix(NFine, world.MLocFine)

    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basisCorrectors = pglod.assembleBasisCorrectors(world, patchT,
                                                    correctorsListT)
    modifiedBasis = basis - basisCorrectors

    bFull = MFull * f_trans
    bFull = basis.T * bFull

    uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions)

    uLodFine = modifiedBasis * uFull
    uLodFine_METHOD = uLodFine
    newErrorFine = np.sqrt(
        np.dot(uLodFine - uFineFull_trans,
               AFine_trans * (uLodFine - uFineFull_trans)))
    print('Method error: {}'.format(newErrorFine))

    print('update all correctors')
    patchT_irrelevant, correctorsListT, KmsijT, csiTNew = zip(
        *map(UpdateCorrectors, range(world.NtCoarse)))

    print('solve the system')
    KFull = pglod.assembleMsStiffnessMatrix(world, patchT, KmsijT)

    MFull = fem.assemblePatchMatrix(NFine, world.MLocFine)

    basis = fem.assembleProlongationMatrix(NWorldCoarse, NCoarseElement)
    basisCorrectors = pglod.assembleBasisCorrectors(world, patchT,
                                                    correctorsListT)
    modifiedBasis = basis - basisCorrectors

    bFull = MFull * f_trans
    bFull = basis.T * bFull

    uFull, _ = pglod.solve(world, KFull, bFull, boundaryConditions)

    uLodFine = modifiedBasis * uFull
    newErrorFine = np.sqrt(
        np.dot(uLodFine - uFineFull_trans,
               AFine_trans * (uLodFine - uFineFull_trans)))
    print('Exact LOD error: {}'.format(newErrorFine))

    return uLodFine_METHOD, uLodFine, uFineFull_pert, MFine
    def StartAlgorithm(self):
        assert (self.init)  # only start the algorithm once

        # in case not every element is affected, the percentage would be missleading.
        eps_size = np.size(self.E_vh)
        self.E_vh = {
            i: self.E_vh[i]
            for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0
        }
        list = [v for v in self.E_vh.values()]
        list.append(0)
        tols = np.sort(list)[::-1]

        eps_size_f = np.size(self.E_vh)
        self.E_f = {
            i: self.E_f[i]
            for i in range(np.size(self.E_f)) if self.E_f[i] > 0
        }
        list_f = [v for v in self.E_f.values()]
        list_f.append(0)
        tols_f = np.sort(list)[::-1]

        # make sure we only update one element all the time
        for i in range(1, np.size(tols)):
            if tols[i] == tols[i - 1]:
                tols[i] -= 1e-7

        for i in range(1, np.size(tols_f)):
            if tols_f[i] == tols_f[i - 1]:
                tols_f[i] -= 1e-7

        full_percentage = len(self.E_vh) / eps_size
        full_percentage_f = len(self.E_f) / eps_size_f

        world = self.world
        print('starting algorithm ...... ')

        TOLt = []
        to_be_updatedT = []
        energy_errorT = []
        rel_energy_errorT = []
        tmp_errorT = []

        offset = []
        TOL = 100  # not relevant

        for i in range(np.size(tols)):
            if TOL == 0:
                pass
            else:
                TOL = tols[i]

            TOLt.append(TOL)
            offset = self.UpdateNextElement(TOL, offset, Printing=False)

            if self.init:
                to_be_updated = np.size(offset) / len(self.E_vh) * 100
                to_be_updatedT.append(to_be_updated)
                pass
            else:
                to_be_updated = np.size(offset) / len(self.E_vh) * 100
                to_be_updatedT.append(to_be_updated * full_percentage)

            KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT,
                                                    self.KmsijT)
            RFull = pglod.assemblePatchFunction(world, self.patchT,
                                                self.RmsijT)
            Rf = pglod.assemblePatchFunction(world, self.patchT,
                                             self.correctorsRhsT)

            basis = fem.assembleProlongationMatrix(world.NWorldCoarse,
                                                   world.NCoarseElement)

            bFull = basis.T * self.MFull * self.f_trans - RFull

            basisCorrectors = pglod.assembleBasisCorrectors(
                world, self.patchT, self.correctorsListT)
            modifiedBasis = basis - basisCorrectors

            uFull, _ = pglod.solve(world, KFull, bFull,
                                   self.boundaryConditions)

            uLodFine = modifiedBasis * uFull
            uLodFine += Rf

            uFineFull_trans_LOD = uLodFine

            if self.init:
                self.init = 0
                uFineFull_trans_LOD_old = uLodFine

            energy_norm = np.sqrt(
                np.dot(uFineFull_trans_LOD,
                       self.AFine_trans * uFineFull_trans_LOD))
            # tmp_error
            tmp_energy_error = np.sqrt(
                np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old),
                       self.AFine_trans *
                       (uFineFull_trans_LOD - uFineFull_trans_LOD_old)))

            # actual error
            if self.compare_with_best_LOD:
                energy_error = np.sqrt(
                    np.dot((uFineFull_trans_LOD - self.u_best_LOD),
                           self.AFine_trans *
                           (uFineFull_trans_LOD - self.u_best_LOD)))
            else:
                energy_error = np.sqrt(
                    np.dot((uFineFull_trans_LOD - self.uFineFull_trans),
                           self.AFine_trans *
                           (uFineFull_trans_LOD - self.uFineFull_trans)))

            uFineFull_trans_LOD_old = uFineFull_trans_LOD

            print(
                ' step({:3d}/{})    TOL: {:f}, updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}'
                .format(i, np.size(tols), TOL, to_be_updated * full_percentage,
                        energy_error, tmp_energy_error,
                        energy_error / energy_norm))

            rel_energy_errorT.append(energy_error / energy_norm)
            energy_errorT.append(energy_error)
            tmp_errorT.append(tmp_energy_error)

            if TOL == 0:
                # stop now
                break

        return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD
    def StartAlgorithm(self):
        assert (self.init)  # only start the algorithm once

        # in case not every element is affected, the percentage would be missleading.
        eps_size = np.size(self.E_vh)
        self.E_vh = {
            i: self.E_vh[i]
            for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0
        }

        full_percentage = len(self.E_vh) / eps_size

        world = self.world
        print('starting algorithm ...... ')

        TOLt = []
        to_be_updatedT = []
        energy_errorT = []
        rel_energy_errorT = []
        tmp_errorT = []

        offset = []
        TOL = 100  # not relevant

        for i in range(len(self.E_vh) + 1):
            if self.init:
                pass
            else:
                offset = self.UpdateNextElement(offset, Printing=False)

            if self.init:
                to_be_updated = np.size(offset) / len(self.E_vh) * 100
                to_be_updatedT.append(to_be_updated)
                pass
            else:
                to_be_updated = np.size(offset) / len(self.E_vh) * 100
                to_be_updatedT.append(to_be_updated * full_percentage)

            KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT,
                                                    self.KmsijT)
            RFull = pglod.assemblePatchFunction(world, self.patchT,
                                                self.RmsijT)
            Rf = pglod.assemblePatchFunction(world, self.patchT,
                                             self.correctorsRhsT)

            basis = fem.assembleProlongationMatrix(world.NWorldCoarse,
                                                   world.NCoarseElement)

            bFull = basis.T * self.MFull * self.f_trans - RFull

            basisCorrectors = pglod.assembleBasisCorrectors(
                world, self.patchT, self.correctorsListT)
            modifiedBasis = basis - basisCorrectors

            uFull, _ = pglod.solve(world, KFull, bFull,
                                   self.boundaryConditions)

            uLodFine = modifiedBasis * uFull
            uLodFine += Rf

            uFineFull_trans_LOD = uLodFine

            if self.init:
                uFineFull_trans_LOD_old = uLodFine

            energy_norm = np.sqrt(
                np.dot(uFineFull_trans_LOD,
                       self.AFine_trans * uFineFull_trans_LOD))
            # tmp_error
            tmp_energy_error = np.sqrt(
                np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old),
                       self.AFine_trans *
                       (uFineFull_trans_LOD - uFineFull_trans_LOD_old)))

            # actual error

            if self.compare_with_best_LOD:
                energy_error = np.sqrt(
                    np.dot((uFineFull_trans_LOD - self.u_best_LOD),
                           self.AFine_trans *
                           (uFineFull_trans_LOD - self.u_best_LOD)))
            else:
                energy_error = np.sqrt(
                    np.dot((uFineFull_trans_LOD - self.uFineFull_trans),
                           self.AFine_trans *
                           (uFineFull_trans_LOD - self.uFineFull_trans)))

            uFineFull_trans_LOD_old = uFineFull_trans_LOD

            if self.init:
                self.init = 0
                print(
                    ' step({:3d}/{})  T: {}  updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}'
                    .format(i, len(self.E_vh), ' - ',
                            to_be_updated * full_percentage, energy_error,
                            tmp_energy_error, energy_error / energy_norm))
            else:
                print(
                    ' step({:3d}/{})  T: {:3d}  updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}'
                    .format(i, len(self.E_vh), offset[-1],
                            to_be_updated * full_percentage, energy_error,
                            tmp_energy_error, energy_error / energy_norm))

            rel_energy_errorT.append(energy_error / energy_norm)
            energy_errorT.append(energy_error)
            tmp_errorT.append(tmp_energy_error)

        return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD
    def StartAlgorithm(self):
        assert (self.init)  # only start the algorithm once

        # in case not every element is affected, the percentage would be missleading.
        eps_size = np.size(self.E_vh)
        self.E_vh = {
            i: self.E_vh[i]
            for i in range(np.size(self.E_vh)) if self.E_vh[i] > 0
        }
        full_percentage = len(self.E_vh) / eps_size

        world = self.world
        print('starting algorithm ...... ')

        TOL = self.StartingTolerance

        TOLt = []
        to_be_updatedT = []
        energy_errorT = []
        rel_energy_errorT = []
        tmp_errorT = []

        offset = []

        continue_computing = 1
        while continue_computing:
            TOLt.append(TOL)
            offset, computed = self.UpdateElements(TOL, offset, Printing=False)

            if computed:
                pass
            else:
                if self.init:
                    pass
                else:
                    to_be_updated = np.size(offset) / len(self.E_vh) * 100
                    to_be_updatedT.append(to_be_updated * full_percentage)

                    energy_errorT.append(energy_error)
                    tmp_errorT.append(old_tmp_energy_error)
                    if np.size(offset) / len(self.E_vh) == 1:
                        print('     every corrector has been updated')
                        continue_computing = 0
                        continue
                    else:
                        print('     skipping TOL {}'.format(TOL))
                        TOL *= 3 / 4.
                        continue

            to_be_updated = np.size(offset) / len(self.E_vh) * 100
            to_be_updatedT.append(to_be_updated * full_percentage)

            KFull = pglod.assembleMsStiffnessMatrix(world, self.patchT,
                                                    self.KmsijT)
            RFull = pglod.assemblePatchFunction(world, self.patchT,
                                                self.RmsijT)
            Rf = pglod.assemblePatchFunction(world, self.patchT,
                                             self.correctorsRhsT)

            basis = fem.assembleProlongationMatrix(world.NWorldCoarse,
                                                   world.NCoarseElement)

            bFull = basis.T * self.MFull * self.f_trans - RFull

            basisCorrectors = pglod.assembleBasisCorrectors(
                world, self.patchT, self.correctorsListT)
            modifiedBasis = basis - basisCorrectors

            uFull, _ = pglod.solve(world, KFull, bFull,
                                   self.boundaryConditions)

            uLodFine = modifiedBasis * uFull
            uLodFine += Rf

            uFineFull_trans_LOD = uLodFine

            if self.init:
                uFineFull_trans_LOD_old = uLodFine
                self.init = 0

            energy_norm = np.sqrt(
                np.dot(uFineFull_trans_LOD,
                       self.AFine_trans * uFineFull_trans_LOD))
            # tmp_error
            tmp_energy_error = np.sqrt(
                np.dot((uFineFull_trans_LOD - uFineFull_trans_LOD_old),
                       self.AFine_trans *
                       (uFineFull_trans_LOD - uFineFull_trans_LOD_old)))
            old_tmp_energy_error = tmp_energy_error

            # actual error
            energy_error = np.sqrt(
                np.dot((uFineFull_trans_LOD - self.uFineFull_trans),
                       self.AFine_trans *
                       (uFineFull_trans_LOD - self.uFineFull_trans)))

            uFineFull_trans_LOD_old = uFineFull_trans_LOD

            print(
                '             TOL: {:f}, updates: {:7.3f}%, energy error: {:f}, tmp_error: {:f}, relative energy error: {:f}'
                .format(TOL, to_be_updated * full_percentage, energy_error,
                        tmp_energy_error, energy_error / energy_norm))

            rel_energy_errorT.append(energy_error / energy_norm)
            energy_errorT.append(energy_error)
            tmp_errorT.append(tmp_energy_error)

            if tmp_energy_error > 1e-5:
                TOL *= 3 / 4.
            else:
                if int(np.size(offset) / len(self.E_vh)) == 1:
                    if computed:
                        print('     stop computing')
                        continue_computing = 0

        return to_be_updatedT, energy_errorT, tmp_errorT, rel_energy_errorT, TOLt, uFineFull_trans_LOD