Пример #1
0
def calc_value_differences(file_path1, file_path2, output_path, func_space,
                           t_func_space, parameters):
    f1 = XDMFFile(file_path1)
    f2 = XDMFFile(file_path2)
    f_out = XDMFFile(output_path)

    value_func1 = Function(func_space)
    value_func2 = Function(func_space)
    result = Function(t_func_space)

    f1.read_checkpoint(value_func1, 'value_func', 0)
    f2.read_checkpoint(value_func2, 'value_func', 0)
    result.vector()[:] \
        = value_func1.vector()[:] - value_func2.vector()[:]
    f_out.write_checkpoint(result, 'diff', parameters.T,
                           XDMFFile.Encoding.HDF5, True)

    i = 1
    dt = parameters.T / parameters.M
    for k in range(parameters.M - 1, -1, -1):
        if k % parameters.save_interval != 0:
            continue
        f1.read_checkpoint(value_func1, 'value_func', i)
        f2.read_checkpoint(value_func2, 'value_func', i)
        result.vector()[:] \
            = value_func1.vector()[:] - value_func2.vector()[:]
        f_out.write_checkpoint(result, 'diff', k * dt, XDMFFile.Encoding.HDF5,
                               True)
        i += 1
Пример #2
0
    class SolutionFile(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_file = XDMFFile(self._full_filename +
                                          "_checkpoint.xdmf")
            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)
            if is_io_process() and 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")

        def write(self, function, name, index):
            assert index in (self._last_index, self._last_index + 1)
            if index == self._last_index + 1:  # writing out solutions after time stepping
                self._update_function_container(function)
                time = float(index)
                self._visualization_file.write(self._function_container, time)
                bak_log_level = get_log_level()
                set_log_level(int(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)
            elif index == self._last_index:
                # corner case for problems with two (or more) unknowns which are written separately to file;
                # one unknown was written to file, while the other was not: since the problem might be coupled,
                # a recomputation of both is required, but there is no need to update storage
                pass
            else:
                raise ValueError("Invalid index")

        def read(self, function, name, index):
            if index <= self._last_index:
                time = float(index)
                self._restart_file.read_checkpoint(function, name, index)
                self._update_function_container(function)
                self._visualization_file.write(self._function_container, time)
            else:
                raise OSError
Пример #3
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_file = XDMFFile(self._full_filename + "_checkpoint.xdmf")
        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:
            self._restart_file.read_checkpoint(self._function_container, name, index)
        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)
            self._restart_file.read_checkpoint(function, name, index)
            self._update_function_container(function)
            self._visualization_file.write(self._function_container, time) # because there is no append option available
        else:
            raise OSError
Пример #4
0
def plot_deltas_2D(vertex_vector, mesh_path, save_dir):
    mesh = Mesh()
    with XDMFFile(mesh_path) as f:
        f.read(mesh)
    V = FunctionSpace(mesh, 'CG', 1)
    value = Function(V)
    value.vector()[:] = vertex_vector[dof_to_vertex_map(V)]
    delta_S = project(value.dx(0), V)
    delta_file = XDMFFile(save_dir)
    delta_file.write_checkpoint(delta_S, 'delta_S', 0, XDMFFile.Encoding.HDF5,
                                True)
    delta_v = project(value.dx(1), V)
    delta_file.write_checkpoint(delta_v, 'delta_v', 0, XDMFFile.Encoding.HDF5,
                                True)
Пример #5
0
def CladdingR_solver(FC_mesh, FC_facets, FC_fs, FC_info, D_post, R_path):

    FC_fi, FC_fo = FC_fs
    h, Tfc_inner, Tb, FC_Tave = FC_info

    # Reading mesh data stored in .xdmf files.
    mesh = Mesh()
    with XDMFFile(FC_mesh) as infile:
        infile.read(mesh)

    mvc = MeshValueCollection("size_t", mesh, 1)
    with XDMFFile(FC_facets) as infile:
        infile.read(mvc, "name_to_read")
    mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)
    #File("Circle_facet.pvd").write(mf)

    # Mesh data
    print('CladdingRod_mesh data\n', 'Number of cells: ', mesh.num_cells(),
          '\n Number of nodes: ', mesh.num_vertices())

    # Define variational problem
    V = FunctionSpace(mesh, 'P', 1)
    u = Function(V)
    v = TestFunction(V)

    # Define boundary conditions base on pygmsh mesh mark
    bc = DirichletBC(V, Constant(Tfc_inner), mf, FC_fi)
    ds = Measure("ds", domain=mesh, subdomain_data=mf, subdomain_id=FC_fo)

    # Variational formulation
    # Klbda_ZrO2 = 18/1000  # W/(m K) --> Nuclear reactor original source
    # Klbda_ZrO2 = Constant(K_ZrO2(FC_Tave))
    F = K_ZrO2(u) * dot(grad(u), grad(v)) * dx + h * (u - Tb) * v * ds

    # Compute solution
    du = TrialFunction(V)
    Gain = derivative(F, u, du)
    solve(F==0, u, bc, J=Gain, \
          solver_parameters={"newton_solver": {"linear_solver": "lu",
                                               "relative_tolerance": 1e-9}}, \
          form_compiler_parameters={"cpp_optimize": True,
                                    "representation": "uflacs",
                                    "quadrature_degree" : 2}
          )  # mumps

    # Save solution
    if D_post:
        fU_out = XDMFFile(os.path.join(R_path, 'FuelCladding', 'u.xdmf'))
        fU_out.write_checkpoint(u, "T", 0, XDMFFile.Encoding.HDF5, False)
        fU_out.close()
Пример #6
0
def FuelR_solver(FR_mesh, FR_facets, FR_f, FRod_info, D_post, R_path):

    Qv, Tfr_outer, FR_Tave = FRod_info

    # Reading mesh data stored in .xdmf files.
    mesh = Mesh()
    with XDMFFile(FR_mesh) as infile:
        infile.read(mesh)

    mvc = MeshValueCollection("size_t", mesh, 1)
    with XDMFFile(FR_facets) as infile:
        infile.read(mvc, "name_to_read")
    mf = cpp.mesh.MeshFunctionSizet(mesh, mvc)
    #File("Circle_facet.pvd").write(mf)

    # Mesh data
    print('FuelRod_mesh data\n', 'Number of cells: ', mesh.num_cells(),
          '\n Number of nodes: ', mesh.num_vertices())

    # Define variational problem
    V = FunctionSpace(mesh, 'P', 1)
    u = Function(V)
    v = TestFunction(V)

    f = Constant(Qv)

    # Define boundary conditions base on pygmsh mesh mark
    bc = DirichletBC(V, Constant(Tfr_outer), mf, FR_f)

    # Variational formulation
    # Klbda_UO2 = Constant(K_UO2(FR_Tave))
    F = K_UO2(u) * dot(grad(u), grad(v)) * dx - f * v * dx

    # Compute solution
    du = TrialFunction(V)
    Gain = derivative(F, u, du)
    solve(F==0, u, bc, J=Gain, \
          solver_parameters={"newton_solver": {"linear_solver": "lu",
                                               "relative_tolerance": 1e-9}}, \
          form_compiler_parameters={"cpp_optimize": True,
                                    "representation": "uflacs",
                                    "quadrature_degree" : 2}
          )  # mumps

    # Save solution
    if D_post:
        fU_out = XDMFFile(os.path.join(R_path, 'FuelRod', 'u.xdmf'))
        fU_out.write_checkpoint(u, "T", 0, XDMFFile.Encoding.HDF5, False)
        fU_out.close()
                              2)

# Set-up Stokes Solve
forms_stokes = FormsStokes(mesh, mixedL, mixedG, alpha,
                           ds=ds).forms_multiphase(rho, ustar, dt, rho * nu, f)
ssc = StokesStaticCondensation(mesh, forms_stokes['A_S'], forms_stokes['G_S'],
                               forms_stokes['B_S'], forms_stokes['Q_S'],
                               forms_stokes['S_S'])

# Loop and output
step = 0
t = 0.

# Store tstep 0
assign(rho, rho0)
xdmf_rho.write_checkpoint(rho, "rho", t)
xdmf_u.write(Uh.sub(0), t)
xdmf_p.write(Uh.sub(1), t)
p.dump2file(mesh, fname_list, property_list, 'wb')
comm.barrier()

# Save some data in txt files
nc = mesh.num_entities_global(2)
npt = p.number_of_particles()

with open(meta_data, "w") as write_file:
    write_file.write("%-12s %-12s %-15s %-20s %-15s %-15s \n" %
                     ("Time step", "Number of steps", "Number of cells",
                      "Number of particles", "Projection", "Solver"))
    write_file.write("%-12.5g %-15d %-15d %-20d %-15s %-15s \n" %
                     (float(dt), num_steps, nc, npt, projection_type, solver))
# Init projection and get initial condition
lstsq_psi = l2projection(p, W, 1)
lstsq_psi.project(psi_h, lb, ub)
assign(psi_h0, psi_h)

step = 0
t = 0.0
area_0 = assemble(psi_h * dx)
(psi_h_min, psi_h_max) = (0.0, 0.0)

timer = Timer()
timer.start()

# Write initial field and dump initial particle field
outfile.write_checkpoint(psi_h, function_name="psi", time_step=0)
p.dump2file(mesh, fname_list, property_list, "wb")

while step < num_steps:
    step += 1
    t += float(dt)

    if comm.Get_rank() == 0:
        print("Step " + str(step))

    # Advect and project
    ap.do_step(float(dt))
    lstsq_psi.project(psi_h, lb, ub)

    psi_h_min = min(psi_h_min, psi_h.vector().min())
    psi_h_max = max(psi_h_max, psi_h.vector().max())
            property_idx,
        )

        # Initialize the l2 projection
        lstsq_psi = l2projection(p, W, property_idx)

        # Set initial condition at mesh and particles
        psi0_h.interpolate(psi0_expression)
        p.interpolate(psi0_h, property_idx)

        step = 0
        area_0 = assemble(psi0_h * dx)
        timer = Timer("[P] Advection loop")
        timer.start()

        output_field.write_checkpoint(psi0_h, function_name="psi", time_step=0)
        while step < num_steps:
            step += 1
            if comm.rank == 0:
                print("Step number" + str(step))

            # Advect particle, assemble and solve pde projection
            t1 = Timer("[P] Advect particles step")
            ap.do_step(float(dt))
            del t1

            if projection_type == "PDE":
                t1 = Timer("[P] Assemble PDE system")
                pde_projection.assemble(True, True)
                del t1
                t1 = Timer("[P] Solve projection")
Пример #10
0
class Solver:
    def __init__(self,
                 fbvp,
                 howard_infsup=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_infsup = howard_infsup
        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, 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 Howard_outer(self, beta):
        # v coresponds to v^{k+1}
        alpha = [0] * self.fbvp.dim
        ell = 0  # iteration counter
        while ell < self.fbvp.parameters.howmaxit:
            ell += 1
            how, alpha = self.Howard_inner(alpha, beta)

        # Create list of vectors (I*v^k+E*v^{k+1} -F) under different controls
        w = np.array(how[:])
        spv = np.array(self.v.vector()[:])
        Ev = [[Exp.dot(spv) for Exp in Exp_b_list]
              for Exp_b_list in self.fbvp.explicit_matrices]

        multlist = np.empty(
            [self.fbvp.csize_beta, self.fbvp.csize_alpha, self.fbvp.dim])
        for ind_b in range(self.fbvp.csize_beta):
            for ind_a in range(self.fbvp.csize_alpha):
                multlist[ind_b][ind_a] = \
                    (self.fbvp.scipy_implicit_matrices[ind_b][ind_a].dot(w) +
                     Ev[ind_b][ind_a] -
                     self.fbvp.forcing_terms[ind_b][ind_a])

        # 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_infsup:
            next_ctr = np.argmin(np.max(multlist, axis=1), axis=0)
        else:
            next_ctr = np.argmax(np.min(multlist, axis=1), axis=0)
        return (how, next_ctr)

    def Howard_inner(self, alpha, beta):
        # v coresponds to v^{k+1}, save it to numpy array
        spv = np.array(self.v.vector()[:])

        Ev = {
            b: [Ea.dot(spv) for Ea in self.fbvp.explicit_matrices[b]]
            for b in set(beta)
        }
        # construct RHS under input control alfa
        rhs = self.v.vector().copy()
        rhs[:] = [
            self.fbvp.forcing_terms[beta[i]][a][i] - Ev[beta[i]][a][i]
            for i, a in enumerate(alpha)
        ]

        # initialise vector with correct dimension to store solution
        how = self.v.vector().copy()

        # initalise matrix with a suitable sparsity pattern
        lhs = self.fbvp.implicit_matrices[0][0].copy()
        # construct implicit matrix under control (alfa, beta)
        for i, a in enumerate(alpha):
            lhs.set([self.fbvp.implicit_matrices[beta[i]][a].getrow(i)[1]],
                    [i], self.fbvp.implicit_matrices[beta[i]][a].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 = np.empty([self.fbvp.csize_alpha, self.fbvp.dim])
        Iw = {
            b: [Ia.dot(spw) for Ia in self.fbvp.scipy_implicit_matrices[b]]
            for b in set(beta)
        }

        for ind_a, _ in enumerate(self.fbvp.ctrset_alpha):
            for j in range(self.fbvp.dim):
                multlist[ind_a][j] = Iw[beta[j]][ind_a][j] \
                    + Ev[beta[j]][ind_a][j] - \
                    self.fbvp.forcing_terms[beta[j]][ind_a][j]

        # 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_infsup:
            next_ctr = [np.argmax(vector) for vector in zip(*multlist)]
        else:
            next_ctr = [np.argmin(vector) for vector in zip(*multlist)]
        return (how, next_ctr)

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

            # update dirichlet boundary conditions if necessary
            if any(boundary_region in
                   self.fbvp.parameters.time_dependent['boundary']
                   for boundary_region in self.fbvp.parameters.omegas):
                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:
                alpha = self.linear_control[0]
                beta = self.linear_control[1]
                A = self.fbvp.implicit_matrices[beta][alpha]
                b = self.v.vector().copy()
                b[:] = (self.fbvp.forcing_terms[beta][alpha] -
                        self.fbvp.explicit_matrices[beta][alpha].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:
                beta = [0] * self.fbvp.dim
                ell = 0  # iteration counter
                while ell < self.fbvp.parameters.howmaxit:
                    ell += 1
                    howit, beta = self.Howard_outer(beta)

            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:
            save_dir = 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,
                       save_dir=save_dir)

    def update_dirichlet_boundary(self, t):
        new_dirichlet_bcs = []
        for region in self.fbvp.parameters.omegas:
            if region in self.fbvp.parameters.time_dependent['boundary']:
                boundary_data = self.fbvp.parameters.RHS_bound[region]
                boundary_data.t = t
                new_dirichlet_bcs.append(
                    DirichletBC(self.fbvp.V, boundary_data,
                                self.fbvp.boundary_markers, region))
            else:
                new_dirichlet_bcs.append(self.fbvp.dirichlet_bcs[region])
        self.fbvp.dirichlet_bcs = new_dirichlet_bcs
Пример #11
0
def heston_transform(parameters,
                     get_error=False,
                     file_path=None,
                     plot_deltas=False):
    experiment = parameters.experiment
    domain_name = parameters.domain
    mesh_name = parameters.mesh

    mesh = Mesh()
    mesh_path = parameters.get_mesh_path()
    with XDMFFile(mesh_path) as f:
        f.read(mesh)

    # Create functions in function spaces defined by both original and
    # transformed meshes and copy value function data from one to another
    t_mesh_path = f'meshes/{domain_name}/t_{domain_name}_{mesh_name}.xdmf'
    if not os.path.exists(t_mesh_path):
        mesh2 = get_original_mesh(t_mesh_path, mesh, parameters)
    else:
        mesh2 = Mesh()
        with XDMFFile(t_mesh_path) as f:
            f.read(mesh2)

    V = FunctionSpace(mesh, 'CG', 1)
    t_V = FunctionSpace(mesh2, 'CG', 1)
    value = Function(V)
    control = Function(V)
    t_value = Function(t_V)
    t_control = Function(t_V)
    if not file_path:
        f = XDMFFile(f'out/{experiment}/{domain_name}/{mesh_name}/v.xdmf')
        t_f = XDMFFile(f'out/{experiment}/{domain_name}/{mesh_name}/t_v.xdmf')
    else:
        f = XDMFFile(file_path)
        path, file_name = os.path.split(file_path)
        t_f = XDMFFile(os.path.join(path, f't_{file_name}'))
    # Save Final Time Condition
    f.read_checkpoint(value, 'value_func', 0)
    t_value.vector()[:] = value.vector()[:]
    t_f.write_checkpoint(t_value, 'value_func', parameters.T)

    # Iterate through remaining timesteps (only some of them are
    #  saved to the file)
    i = 1
    parameters.calculate_save_interval()
    dt = parameters.T / parameters.M
    for k in range(parameters.M - 1, -1, -1):
        if k % parameters.save_interval != 0:
            continue
        f.read_checkpoint(value, 'value_func', i)
        f.read_checkpoint(control, 'control', i - 1)
        t_value.vector()[:] = value.vector()[:]
        t_control.vector()[:] = control.vector()[:]
        t_f.write_checkpoint(t_value, 'value_func', k * dt,
                             XDMFFile.Encoding.HDF5, True)
        t_f.write_checkpoint(t_control, 'control', k * dt,
                             XDMFFile.Encoding.HDF5, True)
        if plot_deltas:
            delta_S = project(t_value.dx(0), t_V)
            t_f.write_checkpoint(delta_S, 'delta_S', k * dt,
                                 XDMFFile.Encoding.HDF5, True)
            delta_v = project(t_value.dx(1), t_V)
            t_f.write_checkpoint(delta_v, 'delta_v', k * dt,
                                 XDMFFile.Encoding.HDF5, True)
        i += 1

        if k == 0 and get_error:
            error_calc(t_value, parameters.t_v_e, mesh2, f't_{mesh_name}',
                       f'out/{experiment}/{domain_name}/errors.json')
Пример #12
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
Пример #13
0
              "newton_solver": {
                  "maximum_iterations": 10
              }
          })
    print('solver done')

    # Save solution to files for visualization and data postprocessing
    _u_A, _u_B, _u_C, _u_T = u_n.split()

    Uvector = 3 * as_backend_type(u_n.vector()).get_local()
    _3u_n.vector().set_local(Uvector)
    _3u_A, _3u_B, _3u_C, _3u_T = _3u_n.split()
    _u_D = _3u_C

    if Data_postprocessing:
        fA_out.write_checkpoint(_u_A, "A", t, XDMFFile.Encoding.HDF5, True)
        fB_out.write_checkpoint(_u_B, "B", t, XDMFFile.Encoding.HDF5, True)
        fC_out.write_checkpoint(_u_C, "C", t, XDMFFile.Encoding.HDF5, True)
        fD_out.write_checkpoint(_u_D, "D", t, XDMFFile.Encoding.HDF5, True)
        fT_out.write_checkpoint(_u_T, "T", t, XDMFFile.Encoding.HDF5, True)

    Twall_n = Twall
    ufl_integral = assemble(_u_T * ds_wall)
    Numer = (roW * Vw *
             Cpw) / dt * Twall_n + fw * Cpw * Tcool_in + hw * A * ufl_integral
    Twall_new = Numer / Denom
    print('Wall temperature {} K'.format(np.around(float(Twall_new), 4)))

    Twall.assign(Twall_new)
    u_n.assign(u)