Ejemplo n.º 1
0
Archivo: io.py Proyecto: mikaem/Oasis
def create_initial_folders(folder, restart_folder, sys_comp, tstep, info_red,
                           scalar_components, output_timeseries_as_vector,
                           **NS_namespace):
    """Create necessary folders."""
    info_red("Creating initial folders")
    # To avoid writing over old data create a new folder for each run
    if MPI.rank(MPI.comm_world) == 0:
        try:
            makedirs(folder)
        except OSError:
            pass

    MPI.barrier(MPI.comm_world)
    newfolder = path.join(folder, 'data')
    if restart_folder:
        newfolder = path.join(newfolder, restart_folder.split('/')[-2])
    else:
        if not path.exists(newfolder):
            newfolder = path.join(newfolder, '1')
        else:
            previous = listdir(newfolder)
            previous = max(map(eval, previous)) if previous else 0
            newfolder = path.join(newfolder, str(previous + 1))

    MPI.barrier(MPI.comm_world)
    if MPI.rank(MPI.comm_world) == 0:
        if not restart_folder:
            #makedirs(path.join(newfolder, "Voluviz"))
            #makedirs(path.join(newfolder, "Stats"))
            #makedirs(path.join(newfolder, "VTK"))
            makedirs(path.join(newfolder, "Timeseries"))
            makedirs(path.join(newfolder, "Checkpoint"))

    tstepfolder = path.join(newfolder, "Timeseries")
    tstepfiles = {}
    comps = sys_comp
    if output_timeseries_as_vector:
        comps = ['p', 'u'] + scalar_components

    for ui in comps:
        tstepfiles[ui] = XDMFFile(MPI.comm_world, path.join(
            tstepfolder, ui + '_from_tstep_{}.xdmf'.format(tstep)))
        tstepfiles[ui].parameters["rewrite_function_mesh"] = False
        tstepfiles[ui].parameters["flush_output"] = True

    return newfolder, tstepfiles
Ejemplo n.º 2
0
def compute_potential(coils, V, dx, mu, sigma, omega, convections,
                      verbose=True,
                      io_submesh=None
                      ):
    '''Compute the magnetic potential :math:`\Phi` with
    :math:`A = \exp(i \omega t) \Phi e_{\\theta}` for a number of coils.
    '''
    # Index all coil rings consecutively, starting with 0.
    # This makes them easier to handle for the equation system.
    physical_indices = []
    new_coils = []
    k = 0
    for coil in coils:
        new_coils.append([])
        for coil_ring in coil['rings']:
            new_coils[-1].append(k)
            physical_indices.append(coil_ring)
            k += 1

    # Set arbitrary reference voltage.
    v_ref = 1.0

    r = Expression('x[0]', degree=1, domain=V.mesh())

    # Compute reference potentials for all coil rings.
    # Prepare the right-hand sides according to :cite:`Cha97`.
    f_list = []
    for k in physical_indices:
        # Real an imaginary parts.
        f_list.append({k: (v_ref * sigma[k] / (2 * pi * r), Constant(0.0))})
    # Solve.
    phi_list = solve_maxwell(V, dx,
                             mu, sigma,
                             omega,
                             f_list,
                             convections,
                             tol=1.0e-12,
                             compute_residuals=False,
                             verbose=True
                             )

    # Write out these phi's to files.
    if io_submesh:
        V_submesh = FunctionSpace(io_submesh, 'CG', 1)
        W_submesh = V_submesh * V_submesh
        from dolfin import interpolate, XDMFFile
        for k, phi in enumerate(phi_list):
            # Restrict to workpiece submesh.
            phi_out = interpolate(phi, W_submesh)
            phi_out.rename('phi%02d' % k, 'phi%02d' % k)
            # Write to file
            phi_file = XDMFFile(io_submesh.mpi_comm(), 'phi%02d.xdmf' % k)
            phi_file.parameters['flush_output'] = True
            phi_file << phi_out
            #plot(phi_out)
            #interactive()

    # Compute weights for the individual coils.
    # First get the voltage--coil-current mapping.
    J = get_voltage_current_matrix(phi_list, physical_indices, dx,
                                   sigma,
                                   omega,
                                   v_ref
                                   )

    num_coil_rings = len(phi_list)
    A = numpy.empty((num_coil_rings, num_coil_rings), dtype=J.dtype)
    b = numpy.empty(num_coil_rings, dtype=J.dtype)
    for k, coil in enumerate(new_coils):
        weight_type = coils[k]['c_type']
        target_value = coils[k]['c_value']
        if weight_type == 'current':
            A, b = prescribe_current(A, b, coil, target_value)
        elif weight_type == 'voltage':
            A, b = prescribe_voltage(A, b, coil, target_value, v_ref, J)
        else:
            raise RuntimeError('Illegal weight type \'%r\'.' % weight_type)

    # TODO write out the equation system to a file
    if io_submesh:
        numpy.savetxt('matrix.dat', A)

    # Solve the system for the weights.
    weights = numpy.linalg.solve(A, b)

    ## Prescribe total power.
    #target_total_power = 4.0e3
    ## Compute all coils with reference voltage.
    #num_coil_rings = J.shape[0]
    #A = numpy.empty((num_coil_rings, num_coil_rings), dtype=J.dtype)
    #b = numpy.empty(num_coil_rings)
    #for k, coil in enumerate(new_coils):
    #    target_value = v_ref
    #    A, b = prescribe_voltage(A, b, coil, target_value, v_ref, J)
    #weights = numpy.linalg.solve(A, b)
    #preliminary_voltages = v_ref * weights
    #preliminary_currents = numpy.dot(J, weights)
    ## Compute resulting total power.
    #total_power = 0.0
    #for coil_loops in new_coils:
    #    # Currents should be the same all over the entire coil,
    #    # so take currents[coil_loops[0]].
    #    total_power += 0.5 \
    #                 * numpy.sum(preliminary_voltages[coil_loops]) \
    #                 * preliminary_currents[coil_loops[0]].real
    #                 # TODO no abs here
    ## Scale all voltages by necessary factor.
    #weights *= numpy.sqrt(target_total_power / total_power)

    if verbose:
        info('')
        info('Resulting voltages,   V/sqrt(2):')
        voltages = v_ref * weights
        info('   %r' % (abs(voltages) / numpy.sqrt(2)))
        info('Resulting currents,   I/sqrt(2):')
        currents = numpy.dot(J, weights)
        info('   %r' % (abs(currents) / numpy.sqrt(2)))
        info('Resulting apparent powers (per coil):')
        for coil_loops in new_coils:
            # With
            #
            #     v(t) = Im(exp(i omega t) v),
            #     i(t) = Im(exp(i omega t) i),
            #
            # the average apparent power over one period is
            #
            #     P_av = omega/(2 pi) int_0^{2 pi/omega} v(t) i(t)
            #          = 1/2 Re(v i*).
            #
            # Currents should be the same all over, so take currents[coil[0]].
            #
            alpha = sum(voltages[coil_loops]) \
                * currents[coil_loops[0]].conjugate()
            power = 0.5 * alpha.real
            info('   %r' % power)
        info('')

    # Compute Phi as the linear combination \sum C_i*phi_i.
    # The function Phi is guaranteed to fulfill the PDE as well (iff the
    # the boundary conditions are linear in phi too).
    #
    # Form $\sum_l c_l \phi_l$.
    # https://answers.launchpad.net/dolfin/+question/214172
    #
    # Unfortunately, one cannot just use
    #     Phi[0].vector()[:] += c.real * phi[0].vector()
    # since phi is from the FunctionSpace V*V and thus .vector() is not
    # available for the individual components.
    #
    Phi = [Constant(0.0),
           Constant(0.0)]
    for phi, c in zip(phi_list, weights):
        # Phi += c * phi
        Phi[0] += c.real * phi[0] - c.imag * phi[1]
        Phi[1] += c.imag * phi[0] + c.real * phi[1]

    # Project the components down to V. This makes various subsequent
    # computations with Phi faster.
    Phi[0] = project(Phi[0], V)
    Phi[0].rename('Re(Phi)', 'Re(Phi)')
    Phi[1] = project(Phi[1], V)
    Phi[1].rename('Im(Phi)', 'Im(Phi)')
    return Phi, voltages
Ejemplo n.º 3
0
def create_xdmf(path, file_name):
    f = XDMFFile(COMM, path + '/' + file_name + '.xdmf')
    # Write out data at every step, at a small performance cost
    f.parameters['flush_output'] = True
    f.parameters['rewrite_function_mesh'] = False
    return f
Ejemplo n.º 4
0
def forward(mu_expression,
            lmbda_expression,
            rho,
            Lx=10,
            Ly=10,
            t_end=1,
            omega_p=5,
            amplitude=5000,
            center=0,
            target=False):
    Lpml = Lx / 10
    #c_p = cp(mu.vector(), lmbda.vector(), rho)
    max_velocity = 200  #c_p.max()

    stable_hx = stable_dx(max_velocity, omega_p)
    nx = int(Lx / stable_hx) + 1
    #nx = max(nx, 60)
    ny = int(Ly * nx / Lx) + 1
    mesh = mesh_generator(Lx, Ly, Lpml, nx, ny)
    used_hx = Lx / nx
    dt = stable_dt(used_hx, max_velocity)
    cfl_ct = cfl_constant(max_velocity, dt, used_hx)
    print(used_hx, stable_hx)
    print(cfl_ct)
    #time.sleep(10)
    PE = FunctionSpace(mesh, "DG", 0)
    mu = interpolate(mu_expression, PE)
    lmbda = interpolate(lmbda_expression, PE)

    m = 2
    R = 10e-8
    t = 0.0
    gamma = 0.50
    beta = 0.25

    ff = MeshFunction("size_t", mesh, mesh.geometry().dim() - 1)
    Dirichlet(Lx, Ly, Lpml).mark(ff, 1)

    # Create function spaces
    VE = VectorElement("CG", mesh.ufl_cell(), 1, dim=2)
    TE = TensorElement("DG", mesh.ufl_cell(), 0, shape=(2, 2), symmetry=True)

    W = FunctionSpace(mesh, MixedElement([VE, TE]))
    F = FunctionSpace(mesh, "CG", 2)
    V = W.sub(0).collapse()
    M = W.sub(1).collapse()

    alpha_0 = Alpha_0(m, stable_hx, R, Lpml)
    alpha_1 = Alpha_1(alpha_0, Lx, Lpml, degree=2)
    alpha_2 = Alpha_2(alpha_0, Ly, Lpml, degree=2)

    beta_0 = Beta_0(m, max_velocity, R, Lpml)
    beta_1 = Beta_1(beta_0, Lx, Lpml, degree=2)
    beta_2 = Beta_2(beta_0, Ly, Lpml, degree=2)

    alpha_1 = interpolate(alpha_1, F)
    alpha_2 = interpolate(alpha_2, F)
    beta_1 = interpolate(beta_1, F)
    beta_2 = interpolate(beta_2, F)

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    a_ = alpha_1 * alpha_2
    b_ = alpha_1 * beta_2 + alpha_2 * beta_1
    c_ = beta_1 * beta_2

    Lambda_e = as_tensor([[alpha_2, 0], [0, alpha_1]])
    Lambda_p = as_tensor([[beta_2, 0], [0, beta_1]])

    # Set up boundary condition
    bc = DirichletBC(W.sub(0), Constant(("0.0", "0.0")), ff, 1)

    # Create measure for the source term
    dx = Measure("dx", domain=mesh)
    ds = Measure("ds", domain=mesh, subdomain_data=ff)

    # Set up initial values
    u0 = Function(V)
    u0.set_allow_extrapolation(True)
    v0 = Function(V)
    a0 = Function(V)
    U0 = Function(M)
    V0 = Function(M)
    A0 = Function(M)

    # Test and trial functions
    (u, S) = TrialFunctions(W)
    (w, T) = TestFunctions(W)

    g = ModifiedRickerPulse(0, omega_p, amplitude, center)

    F = rho * inner(a_ * N_ddot(u, u0, a0, v0, dt, beta) \
        + b_ * N_dot(u, u0, v0, a0, dt, beta, gamma) + c_ * u, w) * dx \
        + inner(N_dot(S, U0, V0, A0, dt, beta, gamma).T * Lambda_e + S.T * Lambda_p, grad(w)) * dx \
        - inner(g, w) * ds \
        + inner(compliance(a_ * N_ddot(S, U0, A0, V0, dt, beta) + b_ * N_dot(S, U0, V0, A0, dt, beta, gamma) + c_ * S, u, mu, lmbda), T) * dx \
        - 0.5 * inner(grad(u) * Lambda_p + Lambda_p * grad(u).T + grad(N_dot(u, u0, v0, a0, dt, beta, gamma)) * Lambda_e \
        + Lambda_e * grad(N_dot(u, u0, v0, a0, dt, beta, gamma)).T, T) * dx \

    a, L = lhs(F), rhs(F)

    # Assemble rhs (once)
    A = assemble(a)

    # Create GMRES Krylov solver
    solver = KrylovSolver(A, "gmres")

    # Create solution function
    S = Function(W)

    if target:
        xdmffile_u = XDMFFile("inversion_temporal_file/target/u.xdmf")
        pvd = File("inversion_temporal_file/target/u.pvd")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries(
            "inversion_temporal_file/target/u_timeseries")
    else:
        xdmffile_u = XDMFFile("inversion_temporal_file/obs/u.xdmf")
        xdmffile_u.write(u0, t)
        timeseries_u = TimeSeries("inversion_temporal_file/obs/u_timeseries")

    rec_counter = 0

    while t < t_end - 0.5 * dt:
        t += float(dt)

        if rec_counter % 10 == 0:
            print(
                '\n\rtime: {:.3f} (Progress: {:.2f}%)'.format(
                    t, 100 * t / t_end), )

        g.t = t

        # Assemble rhs and apply boundary condition
        b = assemble(L)
        bc.apply(A, b)

        # Compute solution
        solver.solve(S.vector(), b)
        (u, U) = S.split(True)

        # Update previous time step
        update(u, u0, v0, a0, beta, gamma, dt)
        update(U, U0, V0, A0, beta, gamma, dt)

        xdmffile_u.write(u, t)
        pvd << (u, t)
        timeseries_u.store(u.vector(), t)

        energy = inner(u, u) * dx
        E = assemble(energy)
        print("E = ", E)
        print(u.vector().max())
# Timestepping
Tend = 2.0
dt = Constant(0.02)
num_steps = np.rint(Tend / float(dt))

# Output directory
store_step = 1
outdir = "./../../results/SlottedDisk_Rotation_AddDelete/"

# Mesh
mesh = Mesh("./../../meshes/circle_0.xml")
mesh = refine(mesh)
mesh = refine(mesh)
mesh = refine(mesh)

outfile = XDMFFile(mesh.mpi_comm(), outdir + "psi_h.xdmf")

# Set slotted disk
psi0_expr = SlottedDisk(radius=rdisk,
                        center=[xc, yc],
                        width=rwidth,
                        depth=0.0,
                        degree=3,
                        lb=lb,
                        ub=ub)

# Function space and velocity field
W = FunctionSpace(mesh, "DG", k)
psi_h = Function(W)

V = VectorFunctionSpace(mesh, "DG", 3)
Ejemplo n.º 6
0
class Solver:
    def __init__(self,
                 fbvp,
                 howard_inf=True,
                 return_result=False,
                 output_mode=True,
                 get_error=False,
                 save_dir=None,
                 linear_mode=False,
                 verbose=True,
                 record_control=True):
        self.fbvp = fbvp
        self.solver = fbvp.parameters.solver
        self.howard_inf = howard_inf
        self.output_mode = output_mode
        self.get_error = get_error
        self.return_result = return_result
        self.linear_mode = linear_mode
        self.record_control = record_control
        if self.linear_mode:
            self.linear_control = 0
        self.verbose = verbose
        # Initialize solution vector with final time data
        self.v = interpolate(fbvp.parameters.ft, fbvp.V)
        self.control = interpolate(Constant(0), fbvp.V)
        if not save_dir:
            save_dir = f'out/{fbvp.parameters.experiment}/'\
                       f'{fbvp.parameters.domain}/{fbvp.mesh_name}/v.xdmf'
        if self.output_mode:
            self.file = XDMFFile(save_dir)
            self.file.parameters['rewrite_function_mesh'] = False
            self.file.write_checkpoint(self.v, 'value_func', fbvp.parameters.T)

        print('Ready to begin calculation')

    def time_iter(self):
        alpha = [0] * self.fbvp.dim  # initialize control
        for k in range(self.fbvp.timesteps - 1, -1, -1):
            time_start = time.perf_counter()
            t = k * self.fbvp.timestep_size  # Current time

            # update dirichlet boundary conditions if necessary
            # TODO: Similar update for Robin boundaries
            if any(elem in self.fbvp.parameters.time_dependent['boundary']
                   for elem in self.fbvp.parameters.regions['Dirichlet']):
                self.update_dirichlet_boundary(t)

            if self.fbvp.parameters.time_dependent['rhs']:
                self.fbvp.assemble_RHS(t)

            if self.fbvp.parameters.time_dependent['pde']:
                self.fbvp.assemble_HJBe(t + self.fbvp.timestep_size)
                self.fbvp.assemble_HJBi(t)

            if self.linear_mode:
                A = self.fbvp.Ilist[self.linear_control]
                b = self.v.vector().copy()
                b[:] = (self.fbvp.Flist[self.linear_control] -
                        self.fbvp.Elist[self.linear_control].dot(
                            np.array(self.v.vector()[:])))
                for bc in self.fbvp.dirichlet_bcs:
                    bc.apply(A, b)
                howit = self.v.vector().copy()
                self.solver.solve(A, howit, b)
            else:
                ell = 0  # iteration counter
                while ell < self.fbvp.parameters.howmaxit:
                    ell += 1
                    howit, alpha = self.Howard(self.v.vector(), alpha)

            self.v.vector()[:] = howit

            if self.output_mode and k % self.fbvp.parameters.save_interval == 0:
                self.file.write_checkpoint(self.v, 'value_func', t,
                                           XDMFFile.Encoding.HDF5, True)

                if self.record_control:
                    self.control.vector()[:] = alpha
                    self.file.write_checkpoint(self.control, 'control', t,
                                               XDMFFile.Encoding.HDF5, True)

            time_elapsed = (time.perf_counter() - time_start)
            if self.verbose:
                print(f'Time step {self.fbvp.timesteps - k} out of'
                      f' {self.fbvp.timesteps} took {time_elapsed}')

        if self.return_result:
            return self.v

        if self.get_error:
            error_file_path = (f'out/{self.fbvp.parameters.experiment}/'
                               f'{self.fbvp.parameters.domain}/errors.json')
            error_calc(self.v, self.fbvp.parameters.v_e, self.fbvp.mesh,
                       self.fbvp.mesh_name, error_file_path)

    def Howard(self, v, alpha):
        # v coresponds to v^{k+1}, save it to numpy array
        spv = np.array(v[:])
        Ev = [E.dot(spv) for E in self.fbvp.explicit_matrices]
        # construct RHS under input control alfa
        rhs = v.copy()
        rhs[:] = [
            self.fbvp.forcing_terms[control][i] - Ev[control][i]
            for i, control in enumerate(alpha)
        ]
        # initialise vector with correct dimension to store solution
        how = v.copy()

        # initalise matrix with a suitable sparameterssity pattern
        lhs = self.fbvp.implicit_matrices[0].copy()
        # construct implicit matrix from control alpha
        for i, control in enumerate(alpha):
            lhs.set([self.fbvp.implicit_matrices[control].getrow(i)[1]], [i],
                    self.fbvp.implicit_matrices[control].getrow(i)[0])
        lhs.apply('insert')

        # solve linear problem to get next iterate of u
        for bc in self.fbvp.dirichlet_bcs:
            bc.apply(lhs, rhs)
        self.solver.solve(lhs, how, rhs)

        # Create list of vectors (I*v^k+E*v^{k+1} -F) under different controls
        spw = np.array(how[:])
        multlist = (Imp.dot(spw) + Exp - F for Imp, Exp, F in zip(
            self.fbvp.scipy_implicit_matrices, Ev, self.fbvp.forcing_terms))

        # Loop over vectors of values of (I*v^k+E*v^{k+1} -F) at each node and
        # record control which optimizes each of them
        if self.howard_inf:
            next_ctr = [np.argmin(vector) for vector in zip(*multlist)]
        else:
            next_ctr = [np.argmax(vector) for vector in zip(*multlist)]
        return (how, next_ctr)

    def update_dirichlet_boundary(self, t):
        new_dirichlet_bcs = []
        for i, region in enumerate(self.fbvp.parameters.regions['Dirichlet']):
            if region in self.fbvp.parameters.time_dependent['boundary']:
                new_dirichlet_bcs.append(
                    self.fbvp.parameters.update_dispenser[region](self.fbvp,
                                                                  t))
            else:
                new_dirichlet_bcs.append(self.fbvp.dirichlet_bcs[i])
        self.fbvp.dirichlet_bcs = new_dirichlet_bcs
Ejemplo n.º 7
0
class SolutionFileXDMF(SolutionFile_Base):
    # DOLFIN 2018.1.0.dev added (throughout the developement cycle) an optional append
    # attribute to XDMFFile.write_checkpoint, which should be set to its non-default value,
    # thus breaking backwards compatibility
    append_attribute = XDMFFile.write_checkpoint.__doc__.find(
        "append: bool") > -1

    def __init__(self, directory, filename):
        SolutionFile_Base.__init__(self, directory, filename)
        self._visualization_file = XDMFFile(self._full_filename + ".xdmf")
        self._visualization_file.parameters["flush_output"] = True
        self._restart_filename = self._full_filename + "_checkpoint.xdmf"
        self._restart_file = XDMFFile(self._restart_filename)
        self._restart_file.parameters["flush_output"] = True

    @staticmethod
    def remove_files(directory, filename):
        SolutionFile_Base.remove_files(directory, filename)
        #
        full_filename = os.path.join(str(directory), filename)

        def remove_files_task():
            if os.path.exists(full_filename + ".xdmf"):
                os.remove(full_filename + ".xdmf")
                os.remove(full_filename + ".h5")
                os.remove(full_filename + "_checkpoint.xdmf")
                os.remove(full_filename + "_checkpoint.h5")

        parallel_io(remove_files_task)

    def write(self, function, name, index):
        time = float(index)
        # Write visualization file (no append available, will overwrite)
        self._update_function_container(function)
        self._visualization_file.write(self._function_container, time)
        # Write restart file. It might be possible that the solution was written to file in a previous run
        # and the execution was interrupted before last written index was updated. In this corner case
        # there would be two functions corresponding to the same time, with two consecutive indices.
        # For now the inelegant way is to try to read: if that works, assume that we are in the corner case;
        # otherwise, we are in the standard case and we should write to file.
        try:
            if os.path.exists(self._restart_filename):
                self._restart_file.read_checkpoint(self._function_container,
                                                   name, index)
            else:
                raise RuntimeError
        except RuntimeError:
            from dolfin.cpp.log import get_log_level, LogLevel, set_log_level
            self._update_function_container(function)
            bak_log_level = get_log_level()
            set_log_level(int(LogLevel.WARNING) + 1)  # disable xdmf logs
            if self.append_attribute:
                self._restart_file.write_checkpoint(self._function_container,
                                                    name,
                                                    time,
                                                    append=True)
            else:
                self._restart_file.write_checkpoint(self._function_container,
                                                    name, time)
            set_log_level(bak_log_level)
            # Once solutions have been written to file, update last written index
        self._write_last_index(index)

    def read(self, function, name, index):
        if index <= self._last_index:
            time = float(index)
            assert os.path.exists(self._restart_filename)
            self._restart_file.read_checkpoint(function, name, index)
            self._update_function_container(function)
            self._visualization_file.write(
                self._function_container,
                time)  # because no append option is available
        else:
            raise OSError
Ejemplo n.º 8
0
# Helper functions for shape calculus
def tan_div(s, n):
    return div(s) - dot(dot(grad(s), n), n)


def dn_mat(s, n):
    return dot(outer(grad(s) * n, n).T, n) - dot(grad(s).T, n)


# Load meshes and mesh-functions used in the MultiMesh from file
multimesh = MultiMesh()
mfs = []
meshes = []
for i in range(2):
    mesh_i = Mesh()
    with XDMFFile("meshes/multimesh_%d.xdmf" % i) as infile:
        infile.read(mesh_i)
    mvc = MeshValueCollection("size_t", mesh_i, 1)
    with XDMFFile("meshes/mf_%d.xdmf" % i) as infile:
        infile.read(mvc, "name_to_read")
    mfs.append(cpp.mesh.MeshFunctionSizet(mesh_i, mvc))
    meshes.append(mesh_i)
    multimesh.add(mesh_i)
multimesh.build()
multimesh.auto_cover(0, Point(1.25, 0.875))
# Create Spatial Coordinates for each mesh
x0 = SpatialCoordinate(meshes[0])
x1 = SpatialCoordinate(meshes[1])


def deformation_vector():
Ejemplo n.º 9
0
    def __init__(self, mesh_name, parameters, alpha_range=None):
        # LOAD MESH AND PARAMETERS
        self.parameters = parameters
        self.mesh_name = mesh_name
        if not alpha_range:
            self.alpha_range = parameters.alpha_range
        else:
            self.alpha_range = alpha_range
        mesh_path = self.parameters.get_mesh_path()

        self.mesh = Mesh()
        with XDMFFile(mesh_path) as f:
            f.read(self.mesh)
        print(f'Mesh size= {self.mesh.hmax()}')
        # dimension of approximation space
        self.dim = len(self.mesh.coordinates())
        print(f'Dimension of solution space is {self.dim}')
        self.V = FunctionSpace(self.mesh, 'CG', 1)  # CG =  P1
        self.coords = self.mesh.coordinates()[dof_to_vertex_map(self.V)]
        self.T = self.parameters.T  # final time
        self.w = TrialFunction(self.V)
        self.u = TestFunction(self.V)
        #######################################################################
        # CONTROL SET CREATION
        self.control_set = np.linspace(self.alpha_range[0],
                                       self.alpha_range[1],
                                       self.parameters.control_set_size)
        self.control_set_size = len(self.control_set)
        print(f'Discretized control set has size {self.control_set_size}')
        #######################################################################
        # BOUNDARY CONDITIONS
        parameters.set_boundary_conditions(self.mesh)
        self.boundary_markers = MeshFunction('size_t', self.mesh, 1)
        self.boundary_markers.set_all(4)  # pylint: disable=no-member

        for i, omega in self.parameters.omegas.items():
            omega.mark(self.boundary_markers, i)

        self.ds = Measure('ds',
                          domain=self.mesh,
                          subdomain_data=self.boundary_markers)

        self.dirichlet_bcs = [
            DirichletBC(self.V, parameters.RHS_bound[j], self.boundary_markers,
                        j) for j in self.parameters.regions["Dirichlet"]
        ]

        # Get indices of dirichlet and robin dofs
        self.dirichlet_nodes_list = set()
        self.dirichlet_nodes_dict = {}
        for j in self.parameters.regions["Dirichlet"]:
            bc = DirichletBC(self.V, Constant(0), self.boundary_markers, j)
            self.dirichlet_nodes_list |= set(bc.get_boundary_values().keys())
            self.dirichlet_nodes_dict[j] = list(
                bc.get_boundary_values().keys())

        self.robin_nodes_list = set()
        self.robin_nodes_dict = {}
        for j in self.parameters.regions["Robin"]:
            bc = DirichletBC(self.V, Constant(0), self.boundary_markers, j)
            self.robin_nodes_list |= set(bc.get_boundary_values().keys())
            self.robin_nodes_dict[j] = list(bc.get_boundary_values().keys())

        bc = DirichletBC(self.V, Constant(0), 'on_boundary')
        self.boundary_nodes_list = bc.get_boundary_values().keys()

        self.robint_nodes_list = set()
        self.robint_nodes_dict = {}
        for j in self.parameters.regions["RobinTime"]:
            bc = DirichletBC(self.V, Constant(0), self.boundary_markers, j)
            self.robint_nodes_list |= set(bc.get_boundary_values().keys())
            self.robint_nodes_dict[j] = list(bc.get_boundary_values().keys())
        #######################################################################
        # ASSEMBLY
        time_start = time.process_time()
        self.assemble_diagonal_matrix()  # auxilliary generic diagonal matrix
        # used for vector*matrix multiplication of dolfin matrices
        self.assemble_lumpedmm()  # lumped mass matrix
        # which serves the role of identity operator
        self.assemble_laplacian()  # discrete laplacian

        self.ad_data_path = f'out/{self.parameters.experiment}'
        Path(self.ad_data_path).mkdir(parents=True, exist_ok=True)

        self.timesteps = self.parameters.get_number_of_timesteps()
        self.assemble_HJBe()  # assembly of explicit operators
        self.assemble_HJBi()  # assembly of implicit operators
        self.assemble_RHS()  # assembly of forcing term
        print('Final time assembly complete')
        print(f'Assembly took {time.process_time() - time_start} seconds')

        print('===========================================================')
Ejemplo n.º 10
0
    def model(self, parameters=None, logger=None):
        def format(arr):
            return np.array(arr)

        # Setup parameters, logger
        self.set_parameters(parameters)
        self.set_logger(logger)

        # Get parameters
        parameters = self.get_parameters()

        #SS#if not parameters.get('simulate'):
        #SS#	return

        # Setup data
        self.set_data(reset=True)
        self.set_observables(reset=True)

        # Show simulation settings
        self.get_logger()('\n\t'.join([
            'Simulating:', *[
                '%s : %r' % (param, parameters[param] if not isinstance(
                    parameters[param], dict) else list(parameters[param]))
                for param in
                ['fields', 'num_elem', 'N', 'dt', 'D', 'alpha', 'tol']
            ]
        ]))

        # Data mesh
        mesh = IntervalMesh(MPI.comm_world, parameters['num_elem'],
                            parameters['L_0'], parameters['L_1'])

        # Fields
        V = {}
        W = {}
        fields_n = {}
        fields = {}
        w = {}
        fields_0 = {}
        potential = {}
        potential_derivative = {}
        bcs = {}
        R = {}
        J = {}
        # v2d_vector = {}
        observables = {}
        for field in parameters['fields']:

            # Define functions
            V[field] = {}
            w[field] = {}
            for space in parameters['spaces']:
                V[field][space] = getattr(
                    dolfin, parameters['spaces'][space]['type'])(
                        mesh, parameters['spaces'][space]['family'],
                        parameters['spaces'][space]['degree'])
                w[field][space] = TestFunction(V[field][space])

            space = V[field][parameters['fields'][field]['space']]
            test = w[field][parameters['fields'][field]['space']]

            fields_n[field] = Function(space, name='%sn' % (field))
            fields[field] = Function(space, name=field)

            # Inital condition
            fields_0[field] = Expression(
                parameters['fields'][field]['initial'],
                element=space.ufl_element())
            fields_n[field] = project(fields_0[field], space)
            fields[field].assign(fields_n[field])

            # Define potential
            if parameters['potential'].get('kwargs') is None:
                parameters['potential']['kwargs'] = {}
            for k in parameters['potential']['kwargs']:
                if parameters['potential']['kwargs'][k] is None:
                    parameters['potential']['kwargs'][k] = fields[k]

            potential[field] = Expression(
                parameters['potential']['expression'],
                degree=parameters['potential']['degree'],
                **parameters['potential']['kwargs'])
            potential_derivative[field] = Expression(
                parameters['potential']['derivative'],
                degree=parameters['potential']['degree'] - 1,
                **parameters['potential']['kwargs'])

            #Subdomain for defining Positive grain
            sub_domains = MeshFunction('size_t', mesh,
                                       mesh.topology().dim(), 0)

            #BC condition
            bcs[field] = []
            if parameters['fields'][field]['bcs'] == 'dirichlet':
                BC_l = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_0'])
                BC_r = CompiledSubDomain('near(x[0], side) && on_boundary',
                                         side=parameters['L_1'])
                bcl = DirichletBC(V, fields_n[field], BC_l)
                bcr = DirichletBC(V, fields_n[field], BC_r)
                bcs[field].extend([bcl, bcr])
            elif parameters['fields'][field]['bcs'] == 'neumann':
                bcs[field].extend([])

            # Residual and Jacobian
            R[field] = (
                ((fields[field] - fields_n[field]) / parameters['dt'] * test *
                 dx) +
                (inner(parameters['D'] * grad(test), grad(fields[field])) * dx)
                + (parameters['alpha'] * potential_derivative[field] * test *
                   dx))

            J[field] = derivative(R[field], fields[field])

            # Observables
            observables[field] = {}

        files = {
            'xdmf': XDMFFile(MPI.comm_world,
                             self.get_paths()['xdmf']),
            'hdf5': HDF5File(MPI.comm_world,
                             self.get_paths()['hdf5'], 'w'),
        }

        files['hdf5'].write(mesh, '/mesh')
        eps = lambda n, key, field, observables, tol: (
            n == 0) or (abs(observables[key]['total_energy'][n] - observables[
                key]['total_energy'][n - 1]) /
                        (observables[key]['total_energy'][0]) > tol)
        flag = {field: True for field in parameters['fields']}
        tol = {
            field: parameters['tol'][field] if isinstance(
                parameters['tol'], dict) else parameters['tol']
            for field in parameters['fields']
        }
        phases = {'p': 1, 'm': 2}
        n = 0
        problem = {}
        solver = {}
        while (n < parameters['N']
               and any([flag[field] for field in parameters['fields']])):

            self.get_logger()('Time: %d' % (n))

            for field in parameters['fields']:

                if not flag[field]:
                    continue

                # Solve
                problem[field] = NonlinearVariationalProblem(
                    R[field], fields[field], bcs[field], J[field])
                solver[field] = NonlinearVariationalSolver(problem[field])
                solver[field].solve()

                # Get field array
                array = assemble(
                    (1 / CellVolume(mesh)) *
                    inner(fields[field], w[field]['Z']) * dx).get_local()

                # Observables
                observables[field]['Time'] = parameters['dt'] * n

                # observables[field]['energy_density'] = format(0.5*dot(grad(fields[field]),grad(fields[field]))*dx)
                observables[field]['gradient_energy'] = format(
                    assemble(0.5 *
                             dot(grad(fields[field]), grad(fields[field])) *
                             dx(domain=mesh)))
                observables[field]['landau_energy'] = format(
                    assemble(potential[field] * dx(domain=mesh)))
                observables[field]['diffusion_energy'] = format(
                    assemble(
                        project(
                            div(project(grad(fields[field]), V[field]['W'])),
                            V[field]['Z']) * dx(domain=mesh))
                )  #Diffusion part of chemical potential
                observables[field]['spinodal_energy'] = format(
                    assemble(
                        potential_derivative[field] *
                        dx(domain=mesh)))  #Spinodal part of chemical potential

                observables[field]['total_energy'] = parameters[
                    'D'] * observables[field]['gradient_energy'] + parameters[
                        'alpha'] * observables[field]['landau_energy']
                observables[field]['chi'] = parameters['alpha'] * observables[
                    field]['diffusion_energy'] - parameters['D'] * observables[
                        field]['spinodal_energy']

                # Phase observables
                sub_domains.set_all(0)
                sub_domains.array()[:] = np.where(array > 0.0, phases['p'],
                                                  phases['m'])

                phases_dxp = Measure('dx',
                                     domain=mesh,
                                     subdomain_data=sub_domains)
                for phase in phases:
                    dxp = phases_dxp(phases[phase])

                    observables[field]['Phi_0%s' % (phase)] = format(
                        assemble(1 * dxp))
                    observables[field]['Phi_1%s' % (phase)] = format(
                        assemble(fields[field] * dxp))
                    observables[field]['Phi_2%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] * dxp))
                    observables[field]['Phi_3%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * dxp))
                    observables[field]['Phi_4%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] * dxp))
                    observables[field]['Phi_5%s' % (phase)] = format(
                        assemble(fields[field] * fields[field] *
                                 fields[field] * fields[field] *
                                 fields[field] * dxp))

                    observables[field]['gradient_energy_%s' %
                                       (phase)] = format(
                                           assemble(
                                               0.5 *
                                               dot(grad(fields[field]),
                                                   grad(fields[field])) * dxp))
                    observables[field]['landau_energy_%s' % (phase)] = format(
                        assemble(potential[field] * dxp))
                    observables[field][
                        'total_energy_%s' %
                        (phase)] = parameters['D'] * observables[field][
                            'gradient_energy_%s' %
                            (phase)] + parameters['alpha'] * observables[
                                field]['landau_energy_%s' % (phase)]

                    observables[field][
                        'diffusion_energy_%s' % (phase)] = format(
                            assemble(
                                project(
                                    div(
                                        project(grad(fields[field]),
                                                V[field]['W'])), V[field]['Z'])
                                * dxp))  #Diffusion part of chemical potential
                    observables[field][
                        'spinodal_energy_%s' % (phase)] = format(
                            assemble(
                                potential_derivative[field] *
                                dxp))  #Spinodal part of chemical potential

                    observables[field][
                        'chi_%s' %
                        (phase)] = parameters['alpha'] * observables[field][
                            'spinodal_energy_%s' %
                            (phase)] - parameters['D'] * observables[field][
                                'diffusion_energy_%s' % (phase)]

                files['hdf5'].write(fields[field], '/%s' % (field), n)
                files['xdmf'].write(fields[field], n)

                fields_n[field].assign(fields[field])

                self.set_data({field: array})
                self.set_observables({field: observables[field]})

                flag[field] = eps(n, field, fields[field],
                                  self.get_observables(), tol[field])

            n += 1

        for file in files:
            files[file].close()

        return
Ejemplo n.º 11
0
    " 0.",
)
u_exact = Expression(U_exact, degree=7, U=float(1.0), nu=float(nu), mode=mode)

f = Constant((0.0, 0.0, 0.0))

# Create mesh
xmin, ymin, zmin = geometry["xmin"], geometry["ymin"], geometry["zmin"]
xmax, ymax, zmax = geometry["xmax"], geometry["ymax"], geometry["zmax"]

mesh = BoxMesh(MPI.comm_world, Point(xmin, ymin, zmin),
               Point(xmax, ymax, zmax), nx, ny, nz)
pbc = PeriodicBoundary(geometry)

# xdmf output
xdmf_u = XDMFFile(mesh.mpi_comm(), outdir_base + "u.xdmf")
xdmf_p = XDMFFile(mesh.mpi_comm(), outdir_base + "p.xdmf")
xdmf_curl = XDMFFile(mesh.mpi_comm(), outdir_base + "curl.xdmf")

# Required elements
W_E_2 = VectorElement("DG", mesh.ufl_cell(), k)
T_E_2 = VectorElement("DG", mesh.ufl_cell(), 0)
Wbar_E_2 = VectorElement("DGT", mesh.ufl_cell(), kbar)
Wbar_E_2_H12 = VectorElement("CG", mesh.ufl_cell(), kbar)["facet"]

Q_E = FiniteElement("DG", mesh.ufl_cell(), k - 1)
Qbar_E = FiniteElement("DGT", mesh.ufl_cell(), k)

# Function spaces for projection
W_2 = FunctionSpace(mesh, W_E_2)
T_2 = FunctionSpace(mesh, T_E_2)
Ejemplo n.º 12
0
R_path = 'Results'  # Path for data storage
Data_postprocessing = True  # Data storage for later visualization & FEniCS computations.

PBR_L = 3.0  # Reactor length, m
PBR_R = 0.0127  # Reactor radius, m
meszf = 0.001  # mesh element size factor

# Mesh generation and formats conversion
Wallboundary_id = 12
Inletboundary_id = 13
Boundary_ids = Wallboundary_id, Inletboundary_id
pygmsh_mesh, pygmsh_facets = Generate_PBRpygmsh((0., PBR_L), (0., PBR_R),
                                                Boundary_ids, meszf)
# Reading mesh data stored in .xdmf files.
mesh = Mesh()
with XDMFFile(pygmsh_mesh) as infile:
    infile.read(mesh)
mvc = MeshValueCollection("size_t", mesh, 1)
with XDMFFile(pygmsh_facets) as infile:
    infile.read(mvc, "name_to_read")
mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)

# Define function spaces for PDEs variational formulation.
P1 = FiniteElement('P', mesh.ufl_cell(),
                   1)  # Lagrange 1-order polynomials family
element = MixedElement([P1, P1, P1, P1])
V = FunctionSpace(mesh, element)

# Splitting test and trial functions
v_A, v_B, v_C, v_T = TestFunctions(V)  # Test functions
u = Function(V)
Ejemplo n.º 13
0
def run_simulation(
        filepath,
        topology_info: int = None,
        top_bc: int = None,
        bot_bc: int = None,
        left_bc: int = None,
        right_bc: int = None,
        geometry: dict = None,
        kappa=3,  #only if geometry is None
        show=True,
        save_solution=False):

    from dolfin import (Mesh, XDMFFile, MeshValueCollection, cpp,
                        FunctionSpace, TrialFunction, TestFunction,
                        DirichletBC, Constant, Measure, inner, nabla_grad,
                        Function, solve, plot, File)
    mesh = Mesh()
    with XDMFFile("%s_triangle.xdmf" % filepath.split('.')[0]) as infile:
        infile.read(mesh)  # read the complete mesh

    mvc_subdo = MeshValueCollection("size_t", mesh,
                                    mesh.geometric_dimension() - 1)
    with XDMFFile("%s_triangle.xdmf" % filepath.split('.')[0]) as infile:
        infile.read(mvc_subdo, "subdomains")  # read the diferent subdomians
    subdomains = cpp.mesh.MeshFunctionSizet(mesh, mvc_subdo)

    mvc = MeshValueCollection("size_t", mesh, mesh.geometric_dimension() - 2)
    with XDMFFile("%s_line.xdmf" % filepath.split('.')[0]) as infile:
        infile.read(mvc, "boundary_conditions")  #read the boundary conditions
    boundary = cpp.mesh.MeshFunctionSizet(mesh, mvc)

    # Define function space and basis functions
    V = FunctionSpace(mesh, "CG", 1)
    u = TrialFunction(V)
    v = TestFunction(V)
    # Boundary conditions
    bcs = []
    for bc_id in topology_info.keys():
        if bc_id[-2:] == "bc":
            if bot_bc is not None and bc_id[:3] == "bot":
                bcs.append(
                    DirichletBC(V, Constant(bot_bc), boundary,
                                topology_info[bc_id]))
            elif left_bc is not None and bc_id[:4] == "left":
                bcs.append(
                    DirichletBC(V, Constant(left_bc), boundary,
                                topology_info[bc_id]))
            elif top_bc is not None and bc_id[:3] == "top":
                bcs.append(
                    DirichletBC(V, Constant(top_bc), boundary,
                                topology_info[bc_id]))
            elif right_bc is not None and bc_id[:5] == "right":
                bcs.append(
                    DirichletBC(V, Constant(right_bc), boundary,
                                topology_info[bc_id]))
            else:
                print(bc_id + " Not assigned as boundary condition ")
            #    raise NotImplementedError

    # Define new measures associated with the interior domains and
    # exterior boundaries
    dx = Measure("dx", subdomain_data=subdomains)
    ds = Measure("ds", subdomain_data=boundary)

    f = Constant(0)
    g = Constant(0)
    if geometry is not None:  # run multipatch implementation (Multiple domains)
        a = []
        L = []
        for patch_id in geometry.keys():
            kappa = geometry[patch_id].get("kappa")
            a.append(
                inner(Constant(kappa) * nabla_grad(u), nabla_grad(v)) *
                dx(topology_info[patch_id]))
            L.append(f * v * dx(topology_info[patch_id]))
        a = sum(a)
        L = sum(L)
    else:
        a = inner(Constant(kappa) * nabla_grad(u), nabla_grad(v)) * dx
        L = f * v * dx

    ## Redefine u as a function in function space V for the solution
    u = Function(V)
    # Solve
    solve(a == L, u, bcs)
    u.rename('u', 'Temperature')
    # Save solution to file in VTK format
    print('  [+] Output to %s_solution.pvd' % filepath.split('.')[0])
    vtkfile = File('%s_solution.pvd' % filepath.split('.')[0])
    vtkfile << u

    if show:
        import matplotlib
        matplotlib.use("Qt5Agg")
        # Plot solution and gradient
        plot(u, title="Temperature")
        plt.gca().view_init(azim=-90, elev=90)
        plt.show()

    dofs = V.tabulate_dof_coordinates().reshape(
        V.dim(),
        mesh.geometry().dim())  #coordinates of nodes
    vals = u.vector().get_local()  #temperature at nodes

    if save_solution:
        from dolfin import HDF5File, MPI
        output_file = HDF5File(MPI.comm_world,
                               filepath.split('.')[0] + "_solution_field.h5",
                               "w")
        output_file.write(u, "solution")
        output_file.close()
    u.set_allow_extrapolation(True)
    return dofs, vals, mesh, u
    for (nx, dt, pres, store_step) in zip(nx_list, dt_list, pres_list, storestep_list):
        if comm.Get_rank() == 0:
            print("Starting computation with grid resolution " + str(nx))

        # Compute num steps till completion
        num_steps = np.rint(Tend / float(dt))

        # Generate mesh
        mesh = Mesh("./../../meshes/circle_0.xml")
        n = nx
        while n > 1:
            mesh = refine(mesh)
            n /= 2

        output_field = XDMFFile(mesh.mpi_comm(), outdir + "psi_h_nx" + str(nx) + ".xdmf")

        # Velocity and initial condition
        V = VectorFunctionSpace(mesh, "DG", 3)
        uh = Function(V)
        uh.assign(Expression(("-Uh*x[1]", "Uh*x[0]"), Uh=Uh, degree=3))

        psi0_expression = GaussianPulse(
            center=(xc, yc), sigma=float(sigma), U=[Uh, Uh], time=0.0, height=1.0, degree=3
        )

        # Generate particles
        x = RandomCircle(Point(x0, y0), r).generate([pres, pres])
        s = np.zeros((len(x), 1), dtype=np.float_)

        # Initialize particles with position x and scalar property s at the mesh