def run_radial_simul(self, my_front_reconstruction, my_front_advancement, my_vertex_or_path, my_param): # setting up the verbosity level of the log at console # setup_logging_to_console(verbosity_level='error') outputfolder = "./Temp_Data/" + my_vertex_or_path + "_radial_" + my_front_advancement + "_" + my_front_reconstruction self.remove(outputfolder) # creating mesh Mesh = CartesianMesh(my_param['Lx'], my_param['Ly'], my_param['Nx'], my_param['Ny']) # solid properties nu = my_param['nu'] # Poisson's ratio youngs_mod = my_param['youngs_mod'] # Young's modulus Eprime = youngs_mod / (1 - nu**2) # plain strain modulus K_Ic = my_param['K_Ic'] # fracture toughness Cl = my_param['Cl'] # Carter's leak off coefficient # material properties Solid = MaterialProperties(Mesh, Eprime, K_Ic, Carters_coef=Cl) # injection parameters Q0 = my_param['Q0'] # injection rate Injection = InjectionProperties(Q0, Mesh) # fluid properties Fluid = FluidProperties(viscosity=my_param['viscosity']) # simulation properties simulProp = SimulationProperties() simulProp.finalTime = my_param[ 'finalTime'] # the time at which the simulation stops simulProp.set_tipAsymptote( my_vertex_or_path ) # tip asymptote is evaluated with the viscosity dominated assumption simulProp.frontAdvancing = my_front_advancement # to set explicit front tracking simulProp.plotFigure = False simulProp.set_solTimeSeries(np.asarray([2, 200, 5000, 30000, 100000])) simulProp.saveTSJump, simulProp.plotTSJump = 5, 5 # save and plot after every five time steps simulProp.set_outputFolder(outputfolder) simulProp.projMethod = my_front_reconstruction simulProp.log2file = False # initialization parameters Fr_geometry = Geometry('radial', radius=my_param['initialR']) init_param = InitializationParameters(Fr_geometry, regime=my_vertex_or_path) # creating fracture object Fr = Fracture(Mesh, init_param, Solid, Fluid, Injection, simulProp) # create a Controller controller = Controller(Fr, Solid, Fluid, Injection, simulProp) # run the simulation exitcode = controller.run() return exitcode, outputfolder
# initializing fracture from fracture_initialization import get_radial_survey_cells initRad = np.pi surv_cells, _, inner_cells = get_radial_survey_cells(Mesh, initRad) surv_cells_dist = np.cos(Mesh.CenterCoor[surv_cells, 0]) + 2.5 - abs( Mesh.CenterCoor[surv_cells, 1]) Fr_geometry = Geometry(shape='level set', survey_cells=surv_cells, tip_distances=surv_cells_dist, inner_cells=inner_cells) from elasticity import load_isotropic_elasticity_matrix C = load_isotropic_elasticity_matrix(Mesh, Eprime) init_param = InitializationParameters(Fr_geometry, regime='static', net_pressure=1e3, elasticity_matrix=C) # creating fracture object Fr = Fracture(Mesh, init_param, Solid, Fluid, Injection, simulProp) # create a Controller controller = Controller(Fr, Solid, Fluid, Injection, simulProp) # run the simulation controller.run() #################### # plotting results # ####################
# interpolating width on cell centers f = interpolate.interp1d(gamma * L * xw[:, 0], L * eps * xw[:, 1], bounds_error=False, fill_value='extrapolate') w = f(Mesh.distCenter) w[w < 0] = 0. # initialization parameters Fr_geometry = Geometry('radial', radius=gamma * L) from elasticity import load_isotropic_elasticity_matrix C = load_isotropic_elasticity_matrix(Mesh, Eprime) init_param = InitializationParameters(Fr_geometry, regime='static', width=w, elasticity_matrix=C, tip_velocity=Vel) # creating fracture object Fr = Fracture(Mesh, init_param, Solid, Fluid, Injection, simulProp) Fr.time = 5e-5 # create a Controller controller = Controller(Fr, Solid,
# simulation properties simulProp = SimulationProperties() simulProp.finalTime = 500 # the time at which the simulation stops simulProp.set_volumeControl( True) # to set up the solver in volume control mode (inviscid fluid) simulProp.tolFractFront = 4e-3 # increase tolerance for the anisotropic case simulProp.remeshFactor = 1.5 # the factor by which the mesh will be compressed. simulProp.set_outputFolder( "./Data/ellipse") # the disk address where the files are saved simulProp.set_simulation_name('anisotropic_toughness_benchmark') simulProp.symmetric = True # solving with faster solver that assumes fracture is symmetric # initializing fracture gamma = (K1c_func(np.pi / 2) / K1c_func(0))**2 # gamma = (Kc1/Kc3)**2 Fr_geometry = Geometry('elliptical', minor_axis=2., gamma=gamma) init_param = InitializationParameters(Fr_geometry, regime='E_K') # creating fracture object Fr = Fracture(Mesh, init_param, Solid, Fluid, Injection, simulProp) # create a Controller controller = Controller(Fr, Solid, Fluid, Injection, simulProp) # run the simulation controller.run() #################### # plotting results # #################### from visualization import *
# fluid properties viscosity = 0.001 / 12 # mu' =0.001 Fluid = FluidProperties(viscosity=viscosity) # simulation properties simulProp = SimulationProperties() simulProp.finalTime = 3e7 # the time at which the simulation stops simulProp.saveTSJump, simulProp.plotTSJump = 3, 5 # save and plot after every 5 time steps simulProp.set_outputFolder( "./Data/MtoMt_FO") # the disk address where the files are saved simulProp.plotVar = ['w', 'regime'] # initializing fracture Fr_geometry = Geometry('radial') init_param = InitializationParameters(Fr_geometry, regime='M', time=50) # creating fracture object Fr = Fracture(Mesh, init_param, Solid, Fluid, Injection, simulProp) # create a Controller controller = Controller(Fr, Solid, Fluid, Injection, simulProp) # run the simulation controller.run() #################### # plotting results # #################### if not os.path.isfile(
def remesh(self, factor, C, coarse_mesh, material_prop, fluid_prop, inj_prop, sim_prop): """ This function compresses the fracture by the given factor once it has reached the end of the mesh. If the compression factor is two, each set of four cells in the fine mesh is replaced by a single cell. The volume of the fracture is conserved upto machine precision. The elasticity matrix and the properties objects are also re-adjusted according to the new mesh. Arguments: factor (float): -- the factor by which the domain is to be compressed. For example, a factor of 2 will merge the adjacent four cells to a single cell. C (ndarray): -- the elasticity matrix to be re-evaluated for the new mesh. coarse_mesh (CartesianMesh): -- the coarse Cartesian mesh. material_prop (MaterialProperties): -- the MaterialProperties object giving the material properties. fluid_prop(FluidProperties): -- the FluidProperties class object giving the fluid properties to be re-evaluated for the new mesh.. inj_prop(InjectionProperties): -- the InjectionProperties class object giving the injection properties to be re-evaluated for the new mesh. sim_prop (SimulationParameters): -- the SimulationParameters class object giving the numerical parameters to be used in the simulation. Returns: Fr_coarse (Fracture): -- the new fracture after re-meshing. """ if self.sgndDist_last is None: self.sgndDist_last = self.sgndDist # interpolate the level set by first advancing and then interpolating SolveFMM(self.sgndDist, self.EltRibbon, self.EltChannel, self.mesh, [], self.EltChannel) sgndDist_coarse = griddata(self.mesh.CenterCoor[self.EltChannel], self.sgndDist[self.EltChannel], coarse_mesh.CenterCoor, method='linear', fill_value=1e10) # avoid adding tip cells from the fine mesh to get into the channel cells of the coarse mesh max_diag = (coarse_mesh.hx**2 + coarse_mesh.hy**2)**0.5 excluding_tip = np.where(sgndDist_coarse <= -max_diag)[0] sgndDist_copy = np.copy(sgndDist_coarse) sgndDist_coarse = np.full(sgndDist_coarse.shape, 1e10, dtype=np.float64) sgndDist_coarse[excluding_tip] = sgndDist_copy[excluding_tip] # enclosing cells for each cell in the grid enclosing = np.zeros((self.mesh.NumberOfElts, 8), dtype=int) enclosing[:, :4] = self.mesh.NeiElements[:, :] enclosing[:, 4] = self.mesh.NeiElements[enclosing[:, 2], 0] enclosing[:, 5] = self.mesh.NeiElements[enclosing[:, 2], 1] enclosing[:, 6] = self.mesh.NeiElements[enclosing[:, 3], 0] enclosing[:, 7] = self.mesh.NeiElements[enclosing[:, 3], 1] if factor == 2.: # finding the intersecting cells of the fine and course mesh intersecting = np.array([], dtype=int) #todo: a description is to be written, its not readable for i in range(-int(((self.mesh.ny - 1) / 2 + 1) / 2) + 1, int(((self.mesh.ny - 1) / 2 + 1) / 2)): center = self.mesh.CenterElts[0] + i * self.mesh.nx row_to_add = np.arange(center - int( ((self.mesh.nx - 1) / 2 + 1) / 2) + 1, center + int( ((self.mesh.nx - 1) / 2 + 1) / 2), dtype=int) intersecting = np.append(intersecting, row_to_add) # getting the corresponding cells of the coarse mesh in the fine mesh corresponding = [] for i in intersecting: corresponding.append( list( self.mesh.locate_element( coarse_mesh.CenterCoor[i, 0], coarse_mesh.CenterCoor[i, 1]))[0]) corresponding = np.asarray(corresponding, dtype=int) # weighted sum to conserve volume upto machine precision w_coarse = np.zeros((coarse_mesh.NumberOfElts, ), dtype=np.float64) w_coarse[intersecting] = (self.w[corresponding] + np.sum( self.w[enclosing[corresponding, :4]] / 2, axis=1) + np.sum( self.w[enclosing[corresponding, 4:8]] / 4, axis=1)) / 4 LkOff = np.zeros((coarse_mesh.NumberOfElts, ), dtype=np.float64) LkOff[intersecting] = ( self.LkOff[corresponding] + np.sum(self.LkOff[enclosing[corresponding, :4]] / 2, axis=1) + np.sum(self.LkOff[enclosing[corresponding, 4:8]] / 4, axis=1)) wHist_coarse = np.zeros((coarse_mesh.NumberOfElts, ), dtype=np.float64) wHist_coarse[intersecting] = (self.wHist[corresponding] + np.sum( self.wHist[enclosing[corresponding, :4]] / 2, axis=1) + np.sum( self.wHist[enclosing[corresponding, 4:8]] / 4, axis=1)) / 4 else: # In case the factor by which mesh is compressed is not 2 w_coarse = griddata(self.mesh.CenterCoor[self.EltChannel], self.w[self.EltChannel], coarse_mesh.CenterCoor, method='linear', fill_value=0.) LkOff = 4 * griddata(self.mesh.CenterCoor[self.EltChannel], self.LkOff[self.EltChannel], coarse_mesh.CenterCoor, method='linear', fill_value=0.) wHist_coarse = griddata(self.mesh.CenterCoor[self.EltChannel], self.wHist[self.EltChannel], coarse_mesh.CenterCoor, method='linear', fill_value=0.) # interpolate last level set by first advancing to the end of the grid and then interpolating SolveFMM(self.sgndDist_last, self.EltRibbon, self.EltChannel, self.mesh, [], self.EltChannel) sgndDist_last_coarse = griddata(self.mesh.CenterCoor[self.EltChannel], self.sgndDist_last[self.EltChannel], coarse_mesh.CenterCoor, method='linear', fill_value=1e10) Fr_Geometry = Geometry(shape='level set', survey_cells=excluding_tip, inner_cells=excluding_tip, tip_distances=-sgndDist_coarse[excluding_tip]) init_data = InitializationParameters(geometry=Fr_Geometry, regime='static', width=w_coarse, elasticity_matrix=C, tip_velocity=np.nan) Fr_coarse = Fracture(coarse_mesh, init_data, solid=material_prop, fluid=fluid_prop, injection=inj_prop, simulProp=sim_prop) # evaluate current level set on the coarse mesh EltRibbon = np.delete( Fr_coarse.EltRibbon, np.where(sgndDist_copy[Fr_coarse.EltRibbon] >= 1e10)[0]) EltChannel = np.delete( Fr_coarse.EltChannel, np.where(sgndDist_copy[Fr_coarse.EltChannel] >= 1e10)[0]) cells_outside = np.arange(coarse_mesh.NumberOfElts) cells_outside = np.delete(cells_outside, EltChannel) SolveFMM(sgndDist_copy, EltRibbon, EltChannel, coarse_mesh, cells_outside, []) # evaluate last level set on the coarse mesh to evaluate velocity of the tip EltRibbon = np.delete( Fr_coarse.EltRibbon, np.where(sgndDist_last_coarse[Fr_coarse.EltRibbon] >= 1e10)[0]) EltChannel = np.delete( Fr_coarse.EltChannel, np.where(sgndDist_last_coarse[Fr_coarse.EltChannel] >= 1e10)[0]) cells_outside = np.arange(coarse_mesh.NumberOfElts) cells_outside = np.delete(cells_outside, EltChannel) SolveFMM(sgndDist_last_coarse, EltRibbon, EltChannel, coarse_mesh, cells_outside, []) if self.timeStep_last is None: self.timeStep_last = 1 Fr_coarse.v = -(sgndDist_copy[Fr_coarse.EltTip] - sgndDist_last_coarse[ Fr_coarse.EltTip]) / self.timeStep_last Fr_coarse.Tarrival[Fr_coarse.EltChannel] = griddata( self.mesh.CenterCoor[self.EltChannel], self.Tarrival[self.EltChannel], coarse_mesh.CenterCoor[Fr_coarse.EltChannel], method='linear') Tarrival_nan = np.where( np.isnan(Fr_coarse.Tarrival[Fr_coarse.EltChannel]))[0] if Tarrival_nan.size > 0: for elt in Tarrival_nan: Fr_coarse.Tarrival[Fr_coarse.EltChannel[elt]] = np.nanmean( Fr_coarse.Tarrival[coarse_mesh.NeiElements[ Fr_coarse.EltChannel[elt]]]) Fr_coarse.TarrvlZrVrtx[Fr_coarse.EltChannel] = griddata( self.mesh.CenterCoor[self.EltChannel], self.TarrvlZrVrtx[self.EltChannel], coarse_mesh.CenterCoor[Fr_coarse.EltChannel], method='linear') # The zero vertex arrival time for the tip elements is taken equal to the corresponding element in the # fine mesh. If not available, average is taken of the enclosing elements to_correct = [] for indx, elt in enumerate(Fr_coarse.EltTip): corr_tip = self.mesh.locate_element(coarse_mesh.CenterCoor[elt, 0], coarse_mesh.CenterCoor[elt, 1])[0] if np.isnan(self.TarrvlZrVrtx[corr_tip]): TarrvlZrVrtx = 0 cnt = 0 for j in range(8): if not np.isnan(self.TarrvlZrVrtx[enclosing[corr_tip][j]]): TarrvlZrVrtx += self.TarrvlZrVrtx[enclosing[corr_tip] [j]] cnt += 1 if cnt > 0: Fr_coarse.TarrvlZrVrtx[elt] = TarrvlZrVrtx / cnt else: to_correct.append(indx) Fr_coarse.TarrvlZrVrtx[elt] = np.nan else: Fr_coarse.TarrvlZrVrtx[elt] = self.TarrvlZrVrtx[corr_tip] if len(to_correct) > 0: for elt in to_correct: Fr_coarse.TarrvlZrVrtx[Fr_coarse.EltTip[elt]] = np.nanmean( Fr_coarse.TarrvlZrVrtx[Fr_coarse.mesh.NeiElements[ Fr_coarse.EltTip[elt]]]) Fr_coarse.LkOff = LkOff Fr_coarse.LkOffTotal = self.LkOffTotal Fr_coarse.injectedVol = self.injectedVol Fr_coarse.efficiency = (Fr_coarse.injectedVol - Fr_coarse.LkOffTotal) / Fr_coarse.injectedVol Fr_coarse.time = self.time Fr_coarse.closed = np.asarray([]) Fr_coarse.wHist = wHist_coarse return Fr_coarse