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
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
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
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)
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()
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")
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
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')
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
"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)