bottom_fracture_edges = ComPASS.find_fracture_edges(bottom_faces) vertices = ComPASS.vertices() edge_centers = np.array( [vertices[edge].mean(axis=0) for edge in bottom_fracture_edges]) neumann_edges = bottom_fracture_edges[inside_heat_source(edge_centers)] ComPASS.set_Neumann_fracture_edges(neumann_edges, Neumann) Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = 0 Neumann.heat_flux = bottom_heat_flux ComPASS.set_Neumann_faces(bottom_faces, Neumann) sys.stdout.write("set initial and BC" + "\n") set_variable_initial_bc_values() sys.stdout.write("set Neumann BC" + "\n") set_variable_boundary_heat_flux() sys.stdout.flush() init_dt = 0.15 * hour final_time = 1000.0 * year output_period = 0.1 * final_time ComPASS.set_maximum_timestep(0.7 * year) standard_loop( initial_timestep=init_dt, final_time=final_time, output_every=20, # , output_period = output_period, specific_outputs=[1. * day], output_every=20, )
# nodeflags[right_node] = right_flag nodeflags[bottom_node] = bottom_flag nodeflags[top_node] = top_flag def select_dirichlet_nodes(): nodeflags = ComPASS.global_nodeflags() return nodeflags != 0 def select_global_rocktype(): cellflags = ComPASS.global_cellflags() rocktype = 1 + ((cellflags - 1) % 2) cellrocktype = ComPASS.global_cellrocktype().reshape((-1, 2)) cellrocktype[:] = np.stack((rocktype, rocktype), axis=-1) ComPASS.set_output_directory_and_logfile(__file__) ComPASS.init( mesh=mesh, set_global_rocktype=select_global_rocktype, set_global_flags=set_physical_flags, set_dirichlet_nodes=select_dirichlet_nodes, ) # set_initial_values() # set_boundary_conditions() standard_loop(initial_timestep=1000000, output_every=1, final_time=200 * year)
newton = Newton(simulation, 1e-5, 3, LinearSolver(1e-6, 150)) context = SimulationContext() context.abort_on_ksp_failure = False context.dump_system_on_ksp_failure = False context.abort_on_newton_failure = False final_time = 2e6 * year # ComPASS.set_maximum_timestep(0.1*final_time) current_time = standard_loop( simulation, final_time=final_time, nitermax=140, time_step_manager=TimeStepManager( 1 * day, # initial time steps increase_factor=1.2, decrease_factor=0.8, minimum_timestep=1e-6, ), context=context, newton=newton, ) T = simulation.cell_states().T zc = simulation.cell_centers()[:, 2] # print(np.linalg.norm(T0-zc*bottom_heat_flux/K_matrix-T, np.inf)<1e-2) # print(ComPASS.get_current_time() < ) # print('Final time:', current_time, current_time/year, current_time >= final_time) # print('Final error:', np.linalg.norm(T0-zc*bottom_heat_flux/K_matrix-T, np.inf)) if current_time < final_time: raise SanityCheckFailure("final time was not reached")
set_dirichlet_states() newton = Newton(1e-5, 3, LinearSolver(1e-8, 150)) context = SimulationContext() context.abort_on_ksp_failure = False context.dump_system_on_ksp_failure = False context.abort_on_newton_failure = False final_time = 10.0 standard_loop( fixed_timestep=1.0, final_time=final_time, output_period=0.1 * final_time, # nitermax=1, context=context, newton=newton, ) def dump_solution(filename="solution.vtu"): mesh = MT.grid3D(**grid_info) MT.to_vtu( mesh, ComPASS.to_output_directory(filename), pointdata={"u": u(ComPASS.vertices())}, celldata={ "u": u(ComPASS.compute_cell_centers()), "uvol":
set_boundary_heat_flux() newton = Newton(simulation, 1e-5, 3, LinearSolver(1e-6, 150)) context = SimulationContext() context.abort_on_ksp_failure = False context.dump_system_on_ksp_failure = False context.abort_on_newton_failure = False final_time = 2e6 * year # ComPASS.set_maximum_timestep(0.1*final_time) current_time = standard_loop( simulation, initial_timestep=1 * day, final_time=final_time, nitermax=140, context=context, newton=newton, ) T = simulation.cell_states().T zc = simulation.cell_centers()[:, 2] # print(np.linalg.norm(T0-zc*bottom_heat_flux/K_matrix-T, np.inf)<1e-2) # print(ComPASS.get_current_time() < ) # print('Final time:', current_time, current_time/year, current_time >= final_time) # print('Final error:', np.linalg.norm(T0-zc*bottom_heat_flux/K_matrix-T, np.inf)) if current_time < final_time: raise SanityCheckFailure("final time was not reached") error_Linf = np.linalg.norm(T0 - zc * bottom_heat_flux / K_matrix - T, np.inf) if error_Linf > 1e-2:
state.context[node_flags == freeflow_flag] = diphasic_with_liq_outflow state.p[node_flags == freeflow_flag] = p0 state.T[node_flags == freeflow_flag] = T0 state.S[node_flags == freeflow_flag] = [0.0, 1.0] state.C[node_flags == freeflow_flag] = [[1.0, 0.0], [0.0, 1.0]] state.FreeFlow_phase_flowrate[node_flags == freeflow_flag] = 0.0 set_FreeFlow_state(simulation.node_states()) # set linear solver properties newton = Newton(simulation, 1e-6, 35, LinearSolver(1e-6, 50)) final_time = 300 * year output_period = 0.05 * final_time timestep = TimeStepManager( initial_timestep=1.0 * day, minimum_timestep=1e-3, maximum_timestep=output_period, increase_factor=1.3, decrease_factor=0.2, ) standard_loop( simulation, final_time=final_time, time_step_manager=timestep, output_period=output_period, newton=newton, )
copy=False).frac == ord("y") ComPASS.dirichlet_node_states().T[bottom_nodes & fracture_nodes] = Tbot_fracture ComPASS.node_states().T[bottom_nodes & fracture_nodes] = Tbot_fracture set_fracture_dirichlet_bottom_temperature() def set_boundary_fluxes(): Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = qmass Neumann.heat_flux = qmass * ComPASS.liquid_molar_enthalpy( pbot, Tbot_fracture) face_centers = np.rec.array(ComPASS.face_centers()) bottom_fracture_edges = ComPASS.find_fracture_edges( ComPASS.compute_face_centers()[:, 2] <= 0) ComPASS.set_Neumann_fracture_edges(bottom_fracture_edges, Neumann) set_boundary_fluxes() final_time = 200 * year output_period = 0.1 * final_time standard_loop( final_time=final_time, output_period=output_period, time_step_manager=TimeStepManager(initial_timestep=1 * minute, maximum_timestep=output_period), )
# 'centerdepth': np.ascontiguousarray(compute_depth(xyz))}), # 'cell_state_%03d.vtu' % ComPASS.mpi.proc_rank # ) ComPASS.set_output_directory_and_logfile(__file__) ComPASS.init( mesh=mesh, set_dirichlet_nodes=select_dirichlet_nodes, fracture_faces=select_fractures, set_global_flags=set_global_flags, cells_permeability=lambda: matrix_permeability, fractures_permeability=lambda: fracture_permeability, ) set_initial_values() set_boundary_conditions() # no longer useful for computation del topo_nodes del bottom_nodes del vertices del mesh del fault_faces_id ComPASS.set_maximum_timestep(1e2 * year) standard_loop(final_time=1e4 * year, output_period=1e3 * year, initial_timestep=1 * year)
face_centers = simulation.face_centers() simulation.set_Neumann_faces(face_centers[:, 2] <= -H, Neumann) set_boundary_heat_flux() # locate dirichlet nodes - not mandatory # we could have identified different regions using nodeflags dirichlet_nodes = np.nonzero(simulation.nodeflags())[0] dirichlet_T = simulation.dirichlet_node_states().T def change_surface_temperature(n, t): dirichlet_T[dirichlet_nodes] = Tmean + deltaT * np.sin(t * (2 * np.pi / year)) final_time = 5 * year output_period = year / 12 standard_loop( simulation, final_time=final_time, time_step_manager=FixedTimeStep(5.0 * day), output_period=output_period, # iteration callbacks are function of the form f(n, t) # where n is the iteration number and t is time # they are called at the end of each successful iteration # you can put as many of them iteration_callbacks=[change_surface_temperature], )
def print_well_data(well_type, data): well_data = list(data) if well_data: for i, wd in enumerate(well_data): print( "on proc %d - %s well data %d" % (rank, well_type, i), "operating code %s" % wd.operating_code, "radius %10.5f" % wd.radius, "limit pressure %10.5e" % (wd.maximum_pressure if well_type == "injection" else wd.minimum_pressure), "imposed_flowrate %10.5f" % wd.imposed_flowrate, "--------------------> injection temperature %10.5f" % wd.injection_temperature, sep="\n", ) else: print("no", well_type, "data on proc", rank) print_well_data("injection", ComPASS.injectors_data()) print_well_data("production", ComPASS.producers_data()) injection_duration = final_time standard_loop(initial_timestep=1e-5, final_time=injection_duration, output_period=output_period) assert ComPASS.get_timestep() == maximum_timestep
def test_simple_tetmesh(): omega_reservoir = 0.15 # reservoir porosity k_reservoir = 1e-12 # reservoir permeability in m^2 K_reservoir = 2 # bulk thermal conductivity in W/m/K gridshape = (1, 1, 1) gridextent = (1e3, 1e3, 1e3) vertices, tets = GT.grid2tets(gridshape, gridextent) tets = [MT.Tetrahedron(MT.idarray(tet)) for tet in tets] mesh = MT.TetMesh.create(vertices, tets) vertices = mesh.vertices_array() zmax = vertices[:, -1].max() topnodes = np.nonzero(vertices[:, -1] == zmax)[0] simulation = ComPASS.load_eos("water2ph") ComPASS.set_output_directory_and_logfile(__file__) def select_dirichlet_nodes(): print("Selecting", topnodes.shape[0], "top nodes.") on_top = np.zeros(mesh.nb_vertices, dtype=np.bool) on_top[topnodes] = True return on_top print("Gravity:", simulation.get_gravity()) simulation.init( mesh=mesh, set_dirichlet_nodes=select_dirichlet_nodes, cell_porosity=omega_reservoir, cell_permeability=k_reservoir, cell_thermal_conductivity=K_reservoir, ) def set_boundary_conditions(): dirichlet = simulation.dirichlet_node_states() dirichlet.p[topnodes] = 1e5 dirichlet.T[topnodes] = degC2K(30) dirichlet.context[:] = 2 dirichlet.S[:] = [0, 1] dirichlet.C[:] = 1.0 def set_initial_values(): for state in [ simulation.node_states(), simulation.fracture_states(), simulation.cell_states(), ]: state.context[:] = 2 state.p[:] = 1e5 state.T[:] = degC2K(30) state.S[:] = [0, 1] state.C[:] = 1.0 set_boundary_conditions() set_initial_values() standard_loop( simulation, initial_timestep=1 * year, final_time=1e3 * year, output_period=1e2 * year, )
production_data = (t, wellhead_state.temperature) else: production_data = None production_data = communicator.gather(production_data, root=master) if rank == master: production_data = [data for data in production_data if data is not None] # We heavily rely on the fact that there is only one production well over the whole field # production data can be duplicated has we collect both own and ghost well data production_temperatures.append(production_data[0]) #%% First loop: injection of hot water injection_duration = 0.1 * final_time standard_loop( initial_timestep=1e-5, final_time=injection_duration, iteration_callbacks=[collect_production_temperatures,], output_period=output_period, ) #%% Second loop: we reinject production water injectors_data = list(ComPASS.injectors_data()) if injectors_data: assert len(injectors_data) == 1 injector_data = injectors_data[0] else: injector_data = None # weak coupling: injection at t_n is production at t_{n-1} def reinject_production(n, t): if rank == master:
states.context[:] = 1 states.p[:] = p_reservoir states.T[:] = Tright states.S[:] = 1 states.C[:] = 1.0 set_states(ComPASS.node_states()) set_states(ComPASS.cell_states()) ComPASS.set_output_directory_and_logfile(__file__) ComPASS.init( mesh=grid, set_dirichlet_nodes=select_dirichlet_nodes, cell_thermal_conductivity=K_reservoir, cell_permeability=k_reservoir, cell_porosity=omega_reservoir, ) set_initial_values() set_boundary_conditions() output_period = final_time / nb_outputs standard_loop( final_time=final_time, output_period=output_period, time_step_manager=TimeStepManager(final_time / (10 * nb_steps), output_period), )
for states in [ simulation.dirichlet_node_states(), simulation.node_states(), simulation.cell_states(), simulation.fracture_states(), ]: set_initial_states(states) def set_boundary_fluxes(): Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = qmass Neumann.heat_flux = qmass * hbottom face_centers = simulation.face_centers() bottom_fracture_edges = simulation.find_fracture_edges( face_centers[:, 2] <= -H) simulation.set_Neumann_fracture_edges(bottom_fracture_edges, Neumann) set_boundary_fluxes() final_time = 50 * year output_period = 0.1 * final_time standard_loop( simulation, initial_timestep=1 * hour, final_time=final_time, output_period=output_period, )
timestep = TimeStepManager( initial_timestep=1, minimum_timestep=1e-7, maximum_timestep=10.0 * year, increase_factor=1.2, decrease_factor=0.2, ) final_time = 100 * hour output_period = final_time * 0.1 end_of_simu = standard_loop( final_time=final_time, output_period=output_period, context=context, newton=newton, time_step_manager=timestep, # iteration_callbacks = [graph_frac] # output_callbacks=[graph_frac] ) print("time after the time loop", end_of_simu / year, "years") # set_boundary_fluxes2new() # final_time2 = Time1 + 23 * hour #2E4 #150 * year # * day # initial_timestep2 = Time1 # Time1 + # output_period2 = final_time2 * 1/23 #3 # Time2 = standard_loop( # final_time = final_time2, # output_period = output_period2, # time_step_manager = TimeStepManager(initial_timestep2, output_period2),
matplotlib.use("Agg") import matplotlib.pyplot as plt import matplotlib.tri as tri def my_graph(n, t): vertices = ComPASS.vertices() states = ComPASS.node_states() where = vertices[:, 1] == 0 x = vertices[:, 0][where] z = vertices[:, 2][where] T = K2degC(states.T[where]) plt.clf() plt.tricontourf(x, z, T, np.linspace(K2degC(T0), K2degC(T1), 10)) plt.title("mon graph au temps %.2f ans" % (t / year)) plt.colorbar() plt.savefig("graph_%05d.png" % n) final_time = 5e1 * year output_period = 1e0 * year ComPASS.set_maximum_timestep(output_period) standard_loop( initial_timestep=30 * day, final_time=final_time, output_period=output_period, output_callbacks=[ my_graph, ], )
states.context[:] = 1 states.p[:] = pright # pleft + (pright - pleft) * (x - grid.origin[0]) / Lx states.T[:] = Tright states.S[:] = 1 states.C[:] = 1.0 set_states(ComPASS.node_states(), ComPASS.vertices()[:, 0]) set_states(ComPASS.cell_states(), ComPASS.compute_cell_centers()[:, 0]) # %%% Simulation %%% ComPASS.set_output_directory_and_logfile(__file__) ComPASS.init( grid=grid, set_dirichlet_nodes=select_dirichlet_nodes, cell_porosity=omega_reservoir, cell_permeability=k_reservoir, cell_thermal_conductivity=K_reservoir, ) set_initial_values() set_boundary_conditions() standard_loop( final_time=final_time, output_period=final_time / 50, initial_timestep=final_time / (10 * nx), )
return (x == x.min()) & (x == x.max()) simulation.init( mesh=grid, cell_permeability=k_matrix, cell_porosity=phi_matrix, cell_thermal_conductivity=K_matrix, set_dirichlet_nodes=dirichlet_nodes, ) initial_state = simulation.build_state(simulation.Context.liquid, p=pR, T=TR) simulation.all_states().set(initial_state) dirichlet = simulation.dirichlet_node_states() dirichlet.set(initial_state) x = simulation.vertices()[:, 0] left = x == x.min() dirichlet.p[left] = pL dirichlet.T[left] = TL current_time = standard_loop( simulation, initial_timestep=1, nitermax=2, output_period=1, ) # simulation results can be directly postprocessed here # from ComPASS.postprocess import postprocess # postprocess(simulation.runtime.output_directory)
context = SimulationContext() context.abort_on_ksp_failure = False context.dump_system_on_ksp_failure = False context.abort_on_newton_failure = False timestep = TimeStepManager( initial_timestep=1000.0, minimum_timestep=1e-8, maximum_timestep=10.0 * year, increase_factor=1.2, decrease_factor=0.2, ) final_time = 300.0 * year output_period = 0.01 * final_time current_time = standard_loop( simulation, final_time=final_time, # output_every=500, context=context, newton=newton, time_step_manager=timestep, # nitermax=1, # iteration_callbacks=[ma_fonction], output_period=output_period, # specific_outputs=[1. * day], output_every=20, ) print("time after the time loop", current_time / year, "years")
def test_more_faults_than_nodes(): L = 1e3 n = 1 gridextent = (L, ) * 3 gridshape = (n, ) * 3 vertices, tets = GT.grid2tets(gridshape, gridextent) tets = np.asarray(tets, dtype=MT.idtype()) mesh = MT.TetMesh.make(vertices, tets) # The plane x-y=0 def on_plane_xy(pts, epsilon): return np.abs(pts[:, 0] - pts[:, 1]) < epsilon # The plane x-z=0 def on_plane_xz(pts, epsilon): return np.abs(pts[:, 0] - pts[:, 2]) < epsilon # The plane y-z=0 def on_plane_yz(pts, epsilon): return np.abs(pts[:, 1] - pts[:, 2]) < epsilon def on_plane(pts, epsilon=1e-10 * L): return (on_plane_xy(pts, epsilon) | on_plane_xz(pts, epsilon) | on_plane_yz(pts, epsilon)) simulation = ComPASS.load_eos("water2ph") ComPASS.set_output_directory_and_logfile(__file__) print("Gravity:", simulation.get_gravity()) def toponodes(): vertices = simulation.global_vertices() z = vertices[:, -1] return z == z.max() def select_fractures(): where = np.zeros(mesh.nb_faces, dtype=np.bool) centers = simulation.compute_global_face_centers() where = on_plane(centers) print( "Nb of nodes", mesh.nb_vertices, "vs", np.count_nonzero(where), "fracture faces", ) return where def select_dirichlet_nodes(): vertices = simulation.global_vertices() z = vertices[:, -1] on_top = toponodes() print("Selecting", np.sum(on_top), "top nodes.") return on_top def set_global_flags(): nodeflags = simulation.global_nodeflags() nodeflags[:] = 0 nodeflags[toponodes()] = 1 def set_boundary_conditions(): dirichlet = simulation.dirichlet_node_states() topnodes = simulation.nodeflags() == 1 dirichlet.p[topnodes] = 1e5 dirichlet.T[topnodes] = degC2K(30) dirichlet.context[:] = 2 dirichlet.S[:] = [0, 1] dirichlet.C[:] = 1.0 def set_initial_values(): for state in [ simulation.node_states(), simulation.fracture_states(), simulation.cell_states(), ]: state.context[:] = 2 state.p[:] = 1e5 state.T[:] = degC2K(30) state.S[:] = [0, 1] state.C[:] = 1.0 simulation.init( mesh=mesh, fracture_faces=select_fractures, set_dirichlet_nodes=select_dirichlet_nodes, cell_permeability=1e-15, cell_porosity=0.1, cell_thermal_conductivity=2, fracture_permeability=1e-15, fracture_porosity=0.5, fracture_thermal_conductivity=2, set_global_flags=set_global_flags, ) set_boundary_conditions() set_initial_values() standard_loop( simulation, initial_timestep=1 * year, final_time=1e3 * year, output_period=1e2 * year, )
p=p_origin, T=Ttop) simulation.all_states().set(initial_state) dirichlet = simulation.dirichlet_node_states() dirichlet.set(initial_state) # will init all variables: context, states... def set_pT_distribution(states, xyz): x, y, z = [xyz[:, j] for j in range(3)] states.p[:] = pressure_gradient(x, y) + hp(z) states.T[:] = geotherm(z) set_pT_distribution(simulation.node_states(), simulation.vertices()) set_pT_distribution(simulation.cell_states(), simulation.compute_cell_centers()) set_pT_distribution(dirichlet, simulation.vertices()) # Close all wells for wid in range(nb_random_wells): simulation.close_well(wid) final_time = 500 * year output_period = 0.1 * final_time standard_loop( simulation, final_time=final_time, time_step_manager=TimeStepManager(1 * year, output_period), output_period=output_period, )
Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = 0.0 Neumann.heat_flux = ComPASS.liquid_molar_enthalpy(p_bot, 400.0, [0.0, 1.0]) ComPASS.set_Neumann_faces(neumann_faces, Neumann) sys.stdout.write("set initial and BC" + "\n") set_variable_initial_bc_values() sys.stdout.write("set Neumann BC" + "\n") set_variable_boundary_heat_flux() sys.stdout.flush() init_dt = 1.0e-3 final_time = 100.0 * year output_period = 0.01 * final_time ComPASS.set_maximum_timestep(0.7 * year) def ma_fonction(it_timestep, time): if it_timestep > 50: ComPASS.mpi.abort() standard_loop( initial_timestep=init_dt, final_time=final_time, output_every=20, # iteration_callbacks=[ma_fonction], # output_period = output_period, specific_outputs=[1. * day], output_every=20, )
set_states(ComPASS.node_states(), verts[:, 0]) set_states(ComPASS.cell_states(), cellcenters[:, 0]) set_initial_values() set_boundary_conditions() def set_boundary_flux(): face_centers = ComPASS.face_centers() x = face_centers[:, 0] y = face_centers[:, 1] # injection 1 on top Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = fluxInj1 ComPASS.set_Neumann_faces(inflow1(x, y), Neumann) # injection 2 on left side Neumann = ComPASS.NeumannBC() Neumann.molar_flux[:] = fluxInj2 ComPASS.set_Neumann_faces(inflow2(x, y), Neumann) set_boundary_flux() final_time = 60 nitermax = 100 dt = 1e-2 standard_loop(final_time=final_time, output_period=2, initial_timestep=dt) # standard_loop(nitermax=nitermax, output_every=1, output_period=10*dt, initial_timestep=dt, newton=CrudeNewton())
states.C[:] = 1.0 for states in [simulation.node_states(), simulation.cell_states()]: set_initial_states(states) def set_dirichlet_states(): states = simulation.dirichlet_node_states() set_initial_states(states) states.T[:] = u(simulation.vertices()) set_dirichlet_states() newton = Newton(simulation, 1e-5, 3, LinearSolver(1e-8, 150)) final_time = 1e2 standard_loop( simulation, initial_timestep=1.0, final_time=final_time, output_period=0.1 * final_time, # nitermax=1, newton=newton, ) vertices = simulation.vertices() usol = simulation.node_states().T assert np.allclose(usol, u(vertices), atol=5e-3)
def collect_node_temperature(iteration, t): if ComPASS.mpi.communicator().size > 1: if ComPASS.mpi.is_on_master_proc: print("WARNING - No output in parallel mode") return print("Collecting temperature at iteration", iteration) print(" and time", t / year, "years") states = simulation.cell_states() cell_temperatures.append((t, np.copy(states.T))) standard_loop( simulation, final_time=final_time, output_period=final_time / 50, time_step_manager=TimeStepManager(final_time / 1e3, 1.0), output_callbacks=(collect_node_temperature,), ) if ComPASS.mpi.communicator().size == 1: assert ComPASS.mpi.is_on_master_proc xy = simulation.compute_cell_centers()[:, 0:2] XX = xy[:, 0].reshape(ny, nx) YY = xy[:, 1].reshape(ny, nx) import ComPASS.utils.mpl_backends as mpl_backends plt = mpl_backends.import_pyplot(False) if plt: plt.clf() for tT in cell_temperatures:
ComPASS.cell_states(), ]: set_initial_states(states) def set_boundary_heat_flux(): Neumann = ComPASS.NeumannBC() Neumann.heat_flux = bottom_heat_flux face_centers = ComPASS.face_centers() ComPASS.set_Neumann_faces(face_centers[:, 2] <= -H, Neumann) set_boundary_heat_flux() newton = Newton(1e-5, 10, LinearSolver(1e-8, 150)) context = SimulationContext() context.abort_on_ksp_failure = True context.dump_system_on_ksp_failure = True context.abort_on_newton_failure = False final_time = 1e4 * year output_period = 1e3 * year standard_loop( final_time=final_time, output_period=output_period, time_step_manager=TimeStepManager(1 * day, 1000 * year), context=context, newton=newton, )
def test__extrems__no_gravity(T_injection_degC=33.0, flow_velocity_m_s=1.0e-6): T_injection = degC2K(T_injection_degC) p0 = 1.0 * bar T0_degC = 5.0 T0 = degC2K(T0_degC) p_outlet = p0 permeability = 1e-12 # m^2 porosity = 0.2 final_time = 1e8 # s rhow = 1000 # kg/m3 Cw = 4200.0 # J/K/kg Kw = 0.6 # W/m/K rhor = 2600.0 # kg/m3 Cr = 800.0 # J/K/kg Kr = 2.0 # W/m/K Keq = (1 - porosity) * Kr + porosity * Kw # grid specifications extent = Lx, Ly, Lz = 1000, 10, 10 shape = nx, ny, nz = 100, 1, 1 origin = (0, -0.5 * Ly, -0.5 * Lz) simulation = ComPASS.load_eos("linear_water") ComPASS.set_output_directory_and_logfile(__file__) simulation.set_gravity(0) simulation.set_rock_volumetric_heat_capacity(rhor * Cr) p = simulation.get_fluid_properties() p.compressibility = 1e-8 grid = ComPASS.Grid(shape=shape, extent=extent, origin=origin) def outlet_nodes(): return simulation.global_vertices()[:, 0] >= Lx simulation.init( grid=grid, cell_permeability=permeability, cell_porosity=porosity, cell_thermal_conductivity=Keq, set_dirichlet_nodes=outlet_nodes, ) def set_initial_states(states): states.context[:] = 1 # liquid states.p[:] = p0 states.T[:] = T0 states.S[:] = 1 states.C[:] = 1.0 # component fraction... here only one component for states in [ simulation.dirichlet_node_states(), simulation.node_states(), simulation.cell_states(), ]: set_initial_states(states) def set_boundary_flux(): Neumann = ComPASS.NeumannBC() specific_massflux = (flow_velocity_m_s * simulation.molar_density(p0, T_injection) / (Ly * Lz)) Neumann.molar_flux[:] = specific_massflux # energy inflow is approximated using p0 Neumann.heat_flux = specific_massflux * simulation.molar_enthalpy( p0, T_injection) simulation.set_Neumann_faces(simulation.face_centers()[:, 0] <= 0, Neumann) set_boundary_flux() output_period = 0.1 * final_time # On teste a chaque pas de temps si les valeurs extremes sont bien sur les bords (boundary_idx, ) = np.where((simulation.vertices()[:, 0] >= Lx) | (simulation.vertices()[:, 0] <= 0)) def valid(arr, atol=1e-3): arr_boundary = arr[boundary_idx] r_min = arr_boundary.min(0) - atol r_max = arr_boundary.max(0) + atol g_min, g_max = arr.min(0), arr.max(0) return np.all((r_min <= g_min) & (g_min <= r_max) & (r_min <= g_max) & (g_max <= r_max)) def valid_current(iteration, time): X = simulation.node_states() assert valid(X.T) assert valid(X.p) assert valid(X.C) ##assert valid(X.S) # NON pas la saturation car la bulle se developpe avant la sortie standard_loop( simulation, final_time=final_time, time_step_manager=TimeStepManager(1 * hour, 0.2 * output_period), output_period=output_period, output_callbacks=[valid_current], )
def set_pT_distribution(states, z): states.p[:] = hp(z) states.T[:] = geotherm(z) set_pT_distribution(simulation.node_states(), simulation.vertices()[:, 2]) set_pT_distribution(simulation.cell_states(), simulation.compute_cell_centers()[:, 2]) set_pT_distribution(dirichlet, simulation.vertices()[:, 2]) standard_loop( simulation, initial_timestep=1, final_time=year, output_period=year / 12, # nitermax=1, ) master_print("\n", "-" * 10, "closing the well", "-" * 10) producers_data = list(simulation.producers_data()) assert len(producers_data) == 1 producers_data[0].imposed_flowrate = 0 standard_loop( simulation, initial_timestep=1, final_time=year, output_period=year / 12,
# set linear solver properties newton = Newton(simulation, 1e-7, 15, LinearSolver(1e-6, 50)) context = SimulationContext() context.abort_on_ksp_failure = False context.dump_system_on_ksp_failure = False context.abort_on_newton_failure = False timestep = TimeStepManager( initial_timestep=100.0, minimum_timestep=1e-3, maximum_timestep=10.0 * year, increase_factor=1.2, decrease_factor=0.2, ) final_time = 100.0 * year output_period = 0.1 * final_time current_time = standard_loop( simulation, final_time=final_time, context=context, newton=newton, time_step_manager=timestep, output_period=output_period, # nitermax=1, ) print("time after the time loop", current_time / year, "years")
T = [] def store_T(iteration, time): # the copy is important here not to have only a view of the latest array # K2degC will generate one T.append((time, K2degC(simulation.cell_states().T))) # https://charms.gitlabpages.inria.fr/ComPASS/python_reference/ComPASS.html#ComPASS.timestep_management.TimeStepManager ts = TimeStepManager(initial_timestep=1 * hour, maximum_timestep=0.2 * output_period) standard_loop( simulation, final_time=final_time, output_period=output_period, output_callbacks=[store_T], time_step_manager=ts, ) # save table with collected temperatures with open("SO1-T.csv", "w") as f: cell_centers = simulation.cell_centers() print(";", " ; ".join([str(xi) for xi in cell_centers[:, 0]]), file=f) for output in T: print(output[0], ";", " ; ".join([str(theta) for theta in output[1]]), file=f) # build analytical solution