def create_ticket(self, payload): # img_name = f'{payload["Date"]}{payload["Session"][:2]}.png' img_name = f'{payload["Date"]}.png' ticket_path = self.ticket_path + f'/{img_name}' # original ticket cticket_path = self.ticket_path + f'/d_{img_name}' # compressed ticket self.w, self.h = 900, 1050 self.interval_y1, self.interval_y2 = 70, 50 self.font_type = 'Deng' # TODO potential bug for Mac system: ttf format is not supported self.font_size1, self.font_size2 = 55, 35 self.font1 = ImageFont.truetype(self.font_type, self.font_size1) self.font2 = ImageFont.truetype(self.font_type, self.font_size2) self.color = "#000000" self.wallpaper = Image.new("RGB", (self.w, self.h), "white") self.draw = ImageDraw.Draw(self.wallpaper) # Begin drawing self.draw_header(payload) self.draw_qrcode(self.create_qrcode(payload["order"])) self.draw_content(payload) self.wallpaper.save(ticket_path, 'png') # Create compressed ticket image # ticket_img = Image.open(ticket_path) # cticket_img = ticket_img.resize((self.w // 2, self.h // 2), Image.ANTIALIAS) # cticket_img.save(cticket_path) cp.print_success(f"Successfully create library ticket for {img_name}")
def compile_time_data(self, load): time_data_i = self.time_data_i model = self.model u = self.solver.u alpha = self.solver.alpha time_data_i["load"] = load time_data_i["stable"] = self.stability.stable time_data_i["# neg ev"] = self.stability.negev time_data_i["elastic_energy"] = assemble( model.elastic_energy_density(model.eps(u), alpha)*model.dx) if self.user_density is not None: time_data_i["elastic_energy"] += assemble(self.user_density*model.dx) time_data_i["dissipated_energy"] = assemble( model.damage_dissipation_density(alpha)*model.dx) # else: # time_data_i["dissipated_energy"] = assemble(disspated_energy*model.dx) time_data_i["eigs"] = self.stability.eigs if hasattr(self.stability, 'eigs') else np.inf ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) self.time_data.append(time_data_i) time_data_pd = pd.DataFrame(self.time_data) return time_data_pd
def pc_setup(self): self.pc = PETSc.PC().create(MPI.comm_world) self.pc.setType("cholesky") if hasattr(self.pc, 'setFactorSolverType'): self.pc.setFactorSolverType("mumps") elif hasattr(self.pc, 'setFactorSolverPackage'): self.pc.setFactorSolverPackage('mumps') else: ColorPrint.print_warn('Could not configure preconditioner')
def create_virtual_openid(self, openid_len=64): config = self.load_config() if not config["chaoyang"]["payload"]["openid"]: rand_str = ''.join( random.choices(string.ascii_uppercase + string.digits, k=openid_len)) cp.print_success(f"Create virtual openid successfully: {rand_str}") config["chaoyang"]["payload"]["openid"] = rand_str self.save_json(config, self.config_path)
def cancel_reserve(self, order): if not order: cp.print_error("Order id should no be empty!") exit(-1) params = { "order": order, } post_json = self._post_payload(self.base_url + self.url_cancel, params) if post_json["reply"] == "ok": cp.print_warning( f'Cancel order "{order}" successfully! {post_json["order_cancel"]}' ) cp.print_info( "Please check appointment information 'check_list.json' for more detail." ) # elif post_json["reply"] == "error": # TODO potential bug: other error string else: cp.print_error( f'Cancel order "{order}" failed! {post_json["msg"]}') self.check_list()
def _get_data(self, buff_api, params=None): self.end_time = time.time() r_num = random.uniform(self.interval_time[0], self.interval_time[1]) if self.end_time - self.start_time < self.interval_time[0]: cp.print_message(f"sleep {r_num:.2f}s") time.sleep(r_num) api_request = self.sess.get(buff_api, params=params) # print(api_request.url) self.start_time = time.time() if api_request.status_code != 200: raise Exception("fail to request api!") data = api_request.json() if data["code"] == "Login Required": raise Exception("login required!") if data["code"] == "Invalid Argument": raise Exception("Invalid Argument!") return data["data"]
def _post_payload(self, buff_api, params=None): params = params if params else self.params post_res = self.sess.post(buff_api, json=params) if post_res.status_code != 200: post_json = json.loads(post_res.text) cp.print_error(f"Post error! {post_json['Message']}") exit(-1) # raise Exception("Fail to post!") else: cp.print_message("Post successfully!") post_text = post_res.text.replace('{"d":null}', '') ## Regular expression to deprive useless '{"d":null}' suffix is deprecated # text_pattern = re.compile(r'{(.+?)}', re.S) # post_text = text_pattern.findall(post_res.text) # post_text = f"{{{post_text[0]}}}" post_json = json.loads(post_text) return post_json
def set_solver_u(self): for option, value in self.parameters["solver_u"].items(): print("setting ", option, value) PETScOptions.set(option, value) solver = PETScSNESSolver() snes = solver.snes() snes.setOptionsPrefix("u_") snes.setType(self.parameters["solver_u"]["u_snes_type"]) ksp = snes.getKSP() ksp.setType("preonly") pc = ksp.getPC() pc.setType("lu") # Namespace mismatch between petsc4py 3.7 and 3.9. if hasattr(pc, 'setFactorSolverType'): pc.setFactorSolverType("mumps") elif hasattr(pc, 'setFactorSolverPackage'): pc.setFactorSolverPackage('mumps') else: ColorPrint.print_warn('Could not configure preconditioner') solver.set_from_options() snes.setFromOptions() self.solver_u = solver
def get_inertia(self, Mat=None, restricted_dof_is=None): if Mat == None: H = dolfin.as_backend_type(dolfin.assemble(self.H)).mat() else: H = Mat if restricted_dof_is is not None: try: H = H.createSubMatrix(restricted_dof_is, restricted_dof_is) except: H = H.getSubMatrix(restricted_dof_is, restricted_dof_is) self.pc.setOperators(H) self.pc.setUp() Fm = self.pc.getFactorMatrix() # myviewer = PETSc.Viewer().createASCII("test.txt", mode=PETSc.Viewer.Format.ASCII_COMMON,comm= PETSc.COMM_WORLD) (neg, zero, pos) = Fm.getInertia() ColorPrint.print_info( "#Eigenvalues of E'': (%s [neg], %s [zero], %s [pos])" % (neg, zero, pos)) if neg: self.stable = False else: self.stable = True return neg
def admissible_interval(self, alpha, alpha_old, beta_n): one = max(1., max(alpha.vector()[:])) self.upperbound = one self.lowerbound = alpha_old # if hasattr(self, 'bcs') and len(self.bcs[0])>0: # assert np.all([self.is_compatible(bc, v_n, homogeneous = True) for bc in self.bcs[0]]), \ # 'displacement test field is not kinematically admissible' # positive part mask = beta_n.vector()[:] > 0. hp2 = (one - alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [np.inf] hp1 = (alpha_old.vector()[mask] - alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [-np.inf] hp = (max(hp1), min(hp2)) # negative part mask = beta_n.vector()[:] < 0. hn2 = (one - alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [-np.inf] hn1 = (alpha_old.vector()[mask] - alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [np.inf] hn = (max(hn2), min(hn1)) hmax = np.array(np.min([hp[1], hn[1]])) hmin = np.array(np.max([hp[0], hn[0]])) hmax_glob = np.array(0.0, 'd') hmin_glob = np.array(0.0, 'd') comm.Allreduce(hmax, hmax_glob, op=mpi4py.MPI.MIN) comm.Allreduce(hmin, hmin_glob, op=mpi4py.MPI.MAX) hmax = float(hmax_glob) hmin = float(hmin_glob) if hmin > 0: ColorPrint.print_warn('Line search troubles: found hmin>0') return 0., np.nan, (0., 0.), 0. if hmax == 0 and hmin == 0: ColorPrint.print_warn('Line search failed: found zero step size') return 0., np.nan, (0., 0.), 0. if hmax < hmin: ColorPrint.print_warn( 'Line search failed: optimal h* not admissible') return 0., np.nan, (0., 0.), 0. # get next perturbation mode return hmin, hmax
def reserve_seat(self): # if self.params["time"]: # time = [self.params["time"]] # else: # time = ["上午", "下午"] # for t in time: ## remove time params = copy.deepcopy(self.params) params['date'] = f"{params['site']}${params['date']}" params.pop('site') params.pop('time') post_json = self._post_payload(self.base_url + self.url_submit, params) self.start_time = time.time() if post_json["reply"] == "ok": print(post_json["list"][0]["msg"]) else: cp.print_error(f'Error: {post_json["msg"]}') while True: self.end_time = time.time() r_num = random.uniform(self.interval_time[0], self.interval_time[1]) if self.end_time - self.start_time < self.interval_time[0]: cp.print_message( f"sleep {r_num:.2f}s, current time: {time.strftime('%H:%M:%S')}" ) time.sleep(r_num) post_json = self._post_payload(self.base_url + self.url_submit, params) self.start_time = time.time() if post_json["reply"] == "ok": print(post_json["list"][0]["msg"]) break # elif post_json["reply"] == "error": # TODO potential bug: other error string else: cp.print_error(f'Error: {post_json["msg"]}') # datetime = self.params["date"]+t datetime = self.params["date"] self.save_json(post_json, f"{self.record_path}/{datetime}.json") self.check_list()
def solve(self): # initialization par = self.parameters it = 0 err_alpha = 1 u = self.u alpha = self.alpha alpha_old = alpha.copy(deepcopy=True) alpha_error = alpha.copy(deepcopy=True) criterion = 1 alt_min_data = {"iterations": [], "alpha_error": [], "alpha_max": []} while criterion > par["tol"] and it < par["max_it"]: it = it + 1 (u_it, u_reason) = self.solver_u.solve(self.problem_u, self.u.vector()) if self.parameters["solver_alpha"] == "snes2": self.set_solver_alpha_snes2() (alpha_it, alpha_reason) = self.solver.solve() elif self.parameters["solver_alpha"] == "snes": self.set_solver_alpha_snes() import pdb pdb.set_trace() (alpha_it, alpha_reason) = self.solver_alpha.solve( self.problem_alpha, self.alpha.vector(), ) del self.solver_alpha elif self.parameters["solver_alpha"] == "tao": (alpha_it, alpha_reason) = self.solver_alpha.solve( self.problem_alpha, self.alpha.vector(), self.problem_alpha.lb.vector(), self.problem_alpha.ub.vector()) irrev = alpha.vector() - self.problem_alpha.lb.vector() if min(irrev[:]) >= 0: ColorPrint.print_pass('') else: ColorPrint.print_warn('Pointwise irrev {}'.format(' NOK')) alpha_error.vector()[:] = alpha.vector() - alpha_old.vector() # crit: energy norm err_alpha = abs(alpha_error.vector().max()) # err_alpha = norm(alpha_error,'h1') criterion = err_alpha alt_min_data["iterations"].append(it) alt_min_data["alpha_error"].append(err_alpha) alt_min_data["alpha_max"].append(alpha.vector().max()) ColorPrint.print_info( "iter {:2d}: alpha_error={:.4g}, alpha_max={:.4g}".format( it, err_alpha, alpha.vector().max())) # update alpha_old.assign(alpha) return (take_last(alt_min_data), alt_min_data)
def traction_test( ell=0.1, degree=1, n=3, nu=0.0, E=1., load_min=0, load_max=2, loads=None, nsteps=20, Lx=1, Ly=0.1, outdir="outdir", postfix='', savelag=1, sigma_D0=1., continuation=False, checkstability=True, configString='' ): # constants ell = ell Lx = Lx Ly = Ly load_min = load_min load_max = load_max nsteps = nsteps outdir = outdir loads=loads savelag = 1 nu = dolfin.Constant(nu) ell = dolfin.Constant(ell) E0 = dolfin.Constant(E) sigma_D0 = E0 n = n continuation = continuation config = json.loads(configString) if configString != '' else '' cmd_parameters = { 'material': { "ell": ell.values()[0], "E": E0.values()[0], "nu": nu.values()[0], "sigma_D0": sigma_D0.values()[0]}, 'geometry': { 'Lx': Lx, 'Ly': Ly, 'n': n, }, 'experiment': { 'signature': '' }, 'stability': { 'checkstability' : checkstability, 'continuation' : continuation }, 'time_stepping': { 'load_min': load_min, 'load_max': load_max, 'nsteps': nsteps, 'outdir': outdir, 'postfix': postfix, 'savelag': savelag}, 'alt_min': {}, "code": {} } if config: for par in config: parameters[par].update(config[par]) else: for par in parameters: parameters[par].update(cmd_parameters[par]) print(parameters) signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir += '-{}{}'.format(signature, cmd_parameters['time_stepping']['postfix']) # outdir += '-{}'.format(cmd_parameters['time_stepping']['postfix']) parameters['time_stepping']['outdir']=outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: '+outdir) with open(os.path.join(outdir, 'rerun.sh'), 'w') as f: configuration = deepcopy(parameters) configuration['time_stepping'].pop('outdir') str(configuration).replace("\'True\'", "True").replace("\'False\'", "False") rerun_cmd = 'python3 {} --config="{}"'.format(__file__, configuration) f.write(rerun_cmd) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) with open(os.path.join(outdir, 'signature.md5'), 'w') as f: f.write(signature) geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) mesh = mshr.generate_mesh(geom, int(float(n * Lx / ell))) meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) bottom = dolfin.CompiledSubDomain("near(x[1],-Ly/2.)", Ly=Ly) top = dolfin.CompiledSubDomain("near(x[1],Ly/2.)", Ly=Ly) left_bottom_pt = dolfin.CompiledSubDomain("near(x[0],-Lx/2.) && near(x[1],-Ly/2.)", Lx=Lx, Ly=Ly) mf = dolfin.MeshFunction("size_t", mesh, 1, 0) right.mark(mf, 1) left.mark(mf, 2) bottom.mark(mf, 3) ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) # Function Spaces V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") state = [u, alpha] Z = dolfin.FunctionSpace(mesh, dolfin.MixedElement([u.ufl_element(),alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) # BCs (homogenous version needed for residual evaluation) ut = dolfin.Expression("t", t=0.0, degree=0) bcs_u = [dolfin.DirichletBC(V_u.sub(0), dolfin.Constant(0), left), dolfin.DirichletBC(V_u.sub(0), ut, right), dolfin.DirichletBC(V_u, (0, 0), left_bottom_pt, method="pointwise")] bcs_alpha = [] # Files for output ColorPrint.print_warn('Outdir = {}'.format(outdir)) file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.parameters["flush_output"] = True file_con = dolfin.XDMFFile(os.path.join(outdir, "cont.xdmf")) file_con.parameters["functions_share_mesh"] = True file_con.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "modes.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_postproc = dolfin.XDMFFile(os.path.join(outdir, "output_postproc.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True # Problem definition model = DamageElasticityModel(state, E0, nu, ell, sigma_D0) model.dx = dx model.ds = ds energy = model.total_energy_density(u, alpha)*model.dx # Alternate minimisation solver solver = solvers.AlternateMinimizationSolver(energy, [u, alpha], [bcs_u, bcs_alpha], parameters=parameters['alt_min']) rP = model.rP(u, alpha, v, beta)*model.dx rN = model.rN(u, alpha, beta)*model.dx stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, rayleigh=[rP, rN], parameters = parameters['stability']) # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability']) # Time iterations load_steps = np.linspace(load_min, load_max, parameters['time_stepping']['nsteps']) if loads: load_steps = loads stability.parameters['checkstability'] = True time_data = [] linesearch = LineSearch(energy, [u, alpha]) alpha_old = dolfin.Function(alpha.function_space()) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) for it, load in enumerate(load_steps): ut.t = load alpha_old.assign(alpha) ColorPrint.print_warn('Solving load t = {:.2f}'.format(load)) # First order stability conditions (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass('Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 print('lmbda min', lmbda_min_prev) print('mineig', mineig) Deltav = (mineig-lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav)*(lmbda_min_prev+dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes print('About to bifurcate load ', load, 'step', it) bifurcation_loads.append(load) print('DEBUG: decide what to do') # save_current_bifurcation = True bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. if stable: solver.update() else: # Continuation iteration = 1 while stable == False: # linesearch perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta h_opt, (hmin, hmax), energy_perturbations = linesearch.search( [u, alpha, alpha_old], perturbation_v, perturbation_beta) if h_opt != 0: save_current_bifurcation = True alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) # admissible uval = u.vector()[:] + h_opt * perturbation_v.vector()[:] aval = alpha.vector()[:] + h_opt * perturbation_beta.vector()[:] u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() # import pdb; pdb.set_trace() (time_data_i, am_iter) = solver.solve() (stable, negev) = stability.solve(alpha_old) ColorPrint.print_pass(' Continuation iteration {}, current state is{}stable'.format(iteration, ' ' if stable else ' un')) iteration += 1 else: # warn ColorPrint.print_warn('Found zero increment, we are stuck in the matrix') ColorPrint.print_warn('Continuing load program') break solver.update() # stable == True time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["elastic_energy"] = dolfin.assemble( model.elastic_energy_density(model.eps(u), alpha)*dx) time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha)*dx) time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev # import pdb; pdb.set_trace() _sigma = model.stress(model.eps(u), alpha) e1 = dolfin.Constant([1, 0]) _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) time_data_i["sigma"] = 1/Ly * dolfin.assemble(_snn*model.ds(1)) time_data_i["S(alpha)"] = dolfin.assemble(1./(model.a(alpha))*model.dx) time_data_i["A(alpha)"] = dolfin.assemble((model.a(alpha))*model.dx) time_data_i["avg_alpha"] = 1/dolfin.assemble(dolfin.project(Constant(1.), V_alpha)*model.dx) * dolfin.assemble(alpha*model.dx) ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if np.mod(it, savelag) == 0: with file_out as file: file.write(alpha, load) file.write(u, load) with file_postproc as file: file.write_checkpoint(alpha, "alpha-{}".format(it), 0, append = True) print('DEBUG: written step ', it) file.read_checkpoint(alpha, 'alpha-{}'.format(it), 0) print('DEBUG: read step {}, load {}'.format(it, load)) print('DEBUG: file {}'.format(os.path.join(outdir, "output_postproc.xdmf"))) # import pdb; pdb.set_trace() if save_current_bifurcation: # modes = np.where(stability.eigs < 0)[0] time_data_i['h_opt'] = h_opt time_data_i['max_h'] = hmax time_data_i['min_h'] = hmin with file_bif as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) print('DEBUG: irrev ', alpha.vector()-alpha_old.vector()) file.write_checkpoint(beta0v, 'beta0', 0, append = True) file.write_checkpoint(alpha_bif_old, 'alpha-old', 0, append=True) file.write_checkpoint(alpha_bif, 'alpha-bif', 0, append=True) file.write_checkpoint(alpha, 'alpha', 0, append=True) np.save(os.path.join(outdir, 'energy_perturbations'), energy_perturbations, allow_pickle=True, fix_imports=True) with file_eig as file: _v = dolfin.project(dolfin.Constant(h_opt)*perturbation_v, V_u) _beta = dolfin.project(dolfin.Constant(h_opt)*perturbation_beta, V_alpha) _v.rename('perturbation displacement', 'perturbation displacement') _beta.rename('perturbation damage', 'perturbation damage') # import pdb; pdb.set_trace() file.write(_v, load) file.write(_beta, load) file.write_checkpoint(_v, 'perturbation_v', 0, append=True) file.write_checkpoint(_beta, 'perturbation_beta', 0, append=True) save_current_bifurcation = False # if np.mod(it, 10) == 0: # alphatest = dolfin.Function(V_alpha) # with dolfin.XDMFFile(os.path.join(outdir, "output_postproc.xdmf")) as f: # f.read_checkpoint(alphatest, "alpha-{}".format(it), 0) # print('DEBUG: read step ', it) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) from post_processing import plot_global_data print(time_data_pd) print() print('Output in: '+outdir) # if size == 1: # plt.figure() # dolfin.plot(alpha) # plt.savefig(os.path.join(outdir, "alpha.png")) # plt.figure() # dolfin.plot(u, mode="displacement") # plt.savefig(os.path.join(outdir, "u.png")) # plt.close('all') return time_data_pd
def traction_1d( ell=0.1, degree=1, n=3, E=1., load_min=0, load_max=2, loads=None, nsteps=20, Lx=1, outdir="outdir", postfix='', savelag=1, sigma_D0=1., continuation=False, checkstability=True, configString='', breakifunstable=False, ): # constants ell = ell Lx = Lx load_min = load_min load_max = load_max nsteps = nsteps outdir = outdir loads = loads savelag = 1 ell = dolfin.Constant(ell) E0 = dolfin.Constant(E) sigma_D0 = E0 n = n continuation = continuation config = json.loads(configString) if configString != '' else '' cmd_parameters = { 'material': { "ell": ell.values()[0], "E": E0.values()[0], "sigma_D0": sigma_D0.values()[0] }, 'geometry': { 'Lx': Lx, 'n': n, }, 'experiment': { 'signature': '', 'break-if-unstable': breakifunstable }, 'stability': { 'checkstability': checkstability, 'continuation': continuation }, 'time_stepping': { 'load_min': load_min, 'load_max': load_max, 'nsteps': nsteps, 'outdir': outdir, 'postfix': postfix, 'savelag': savelag }, 'alt_min': {}, "code": {} } if config: for par in config: parameters[par].update(config[par]) else: for par in parameters: parameters[par].update(cmd_parameters[par]) print(parameters) signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir += '-{}{}'.format(signature, cmd_parameters['time_stepping']['postfix']) # outdir += '-{}'.format(cmd_parameters['time_stepping']['postfix']) parameters['time_stepping']['outdir'] = outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ' + outdir) with open(os.path.join(outdir, 'rerun.sh'), 'w') as f: configuration = deepcopy(parameters) configuration['time_stepping'].pop('outdir') str(configuration).replace("\'True\'", "True").replace("\'False\'", "False") rerun_cmd = 'python3 {} --config="{}"'.format( os.path.basename(__file__), configuration) f.write(rerun_cmd) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) with open(os.path.join(outdir, 'signature.md5'), 'w') as f: f.write(signature) print('experiment = {}'.format( os.path.join('~/Documents/WIP/paper_stability_code', outdir))) mesh = dolfin.IntervalMesh(int(float(n * Lx / ell)), -Lx / 2., Lx / 2.) meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) mf = dolfin.MeshFunction("size_t", mesh, 1, 0) right.mark(mf, 1) left.mark(mf, 2) # bottom.mark(mf, 3) ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) # Function Spaces V_u = dolfin.FunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") state = [u, alpha] Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) # BCs (homogenous version needed for residual evaluation) ut = dolfin.Expression("t", t=0.0, degree=0) bcs_u = [ dolfin.DirichletBC(V_u, dolfin.Constant(0), left), dolfin.DirichletBC(V_u, ut, right) ] bcs_alpha = [] # bcs_alpha = [dolfin.DirichletBC(V_alpha, dolfin.Constant(1.), right)] # Files for output ColorPrint.print_warn('Outdir = {}'.format(outdir)) file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.parameters["flush_output"] = True file_con = dolfin.XDMFFile(os.path.join(outdir, "cont.xdmf")) file_con.parameters["functions_share_mesh"] = True file_con.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "modes.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True # Problem definition # model = DamageElasticityModel1D(state, E0, ell, sigma_D0) # k_ell = 1e-8 a = (1 - alpha)**2. + k_ell w_1 = parameters['material']['sigma_D0']**2 / parameters['material']['E'] w = w_1 * alpha eps = u.dx(0) # sigma = parameters['material']['E']*eps # energy = 1./2.* parameters['material']['E']*a*eps**2. * dx + (w + w_1 * parameters['material']['ell'] ** 2. * alpha.dx(0)**2.)*dx # # Rayleigh Ratio # rP = (dolfin.sqrt(a)*sigma + dolfin.diff(a, alpha)/dolfin.sqrt(a)*sigma*beta)*(dolfin.sqrt(a)*v.dx(0) + dolfin.diff(a, alpha)/dolfin.sqrt(a)*eps*beta)*dx + \ # 2*w_1*parameters['material']['ell'] ** 2 * beta.dx(0)**2*dx # da = dolfin.diff(a, alpha) # dda = dolfin.diff(dolfin.diff(a, alpha), alpha) # ddw = dolfin.diff(dolfin.diff(w, alpha), alpha) # rN = -(1./2.*(dda - da**2./a)*sigma*eps +1./2.*ddw)*beta**2.*dx # import pdb; pdb.set_trace() # ------------------------------ model = DamageElasticityModel1D(state, E0, ell, sigma_D0) model.dx = dx # energy = model.total_energy_density(u, alpha)*model.dx energy = 1. / 2. * parameters['material']['E'] * a * eps**2. * dx + ( w + w_1 * parameters['material']['ell']**2. * alpha.dx(0)**2.) * dx rP = model.rP(u, alpha, v, beta) * model.dx rN = model.rN(u, alpha, beta) * model.dx # Alternate minimisation solver # import pdb; pdb.set_trace() solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [bcs_u, bcs_alpha], parameters=parameters['alt_min']) stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, rayleigh=[rP, rN], parameters=parameters['stability']) # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability']) # Time iterations load_steps = np.linspace(load_min, load_max, parameters['time_stepping']['nsteps']) # load_steps = np.logspace(np.log10(load_min), np.log10(load_max), parameters['time_stepping']['nsteps']) if loads: load_steps = loads stability.parameters['checkstability'] = True time_data = [] linesearch = LineSearch(energy, [u, alpha]) alpha_old = dolfin.Function(alpha.function_space()) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] time_data_pd = [] for it, load in enumerate(load_steps): # import pdb; pdb.set_trace() ut.t = load alpha_old.assign(alpha) ColorPrint.print_warn('Solving load t = {:.2f}'.format(load)) # First order stability conditions (time_data_i, am_iter) = solver.solve() # import pdb; pdb.set_trace() # Second order stability conditions (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass( 'Current state is{}stable'.format(' ' if stable else ' un')) solver.update() # mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 print('lmbda min', lmbda_min_prev) print('mineig', mineig) Deltav = (mineig - lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav) * (lmbda_min_prev + dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes print('About to bifurcate load ', load, 'step', it) bifurcation_loads.append(load) modes = np.where(stability.eigs < 0)[0] with dolfin.XDMFFile(os.path.join(outdir, "postproc.xdmf")) as file: leneigs = len(modes) maxmodes = min(3, leneigs) for n in range(maxmodes): mode = dolfin.project(stability.linsearch[n]['beta_n'], V_alpha) modename = 'beta-%d' % n print(modename) file.write_checkpoint(mode, modename, 0, append=True) bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. # stable == True time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["elastic_energy"] = dolfin.assemble( 1. / 2. * parameters['material']['E'] * a * eps**2. * dx) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * parameters['material']['ell']**2. * alpha.dx(0)**2.) * dx) time_data_i["elastic_energy"] = dolfin.assemble( model.elastic_energy_density(u.dx(0), alpha) * dx) time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha) * dx) time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev # import pdb; pdb.set_trace() # time_data_i["S(alpha)"] = dolfin.assemble(1./(a)*dx) # time_data_i["a(alpha)"] = dolfin.assemble(a*dx) # time_data_i["avg_alpha"] = dolfin.assemble(alpha*dx) ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if np.mod(it, savelag) == 0: with file_out as f: f.write(alpha, load) f.write(u, load) with dolfin.XDMFFile(os.path.join(outdir, "output_postproc.xdmf")) as f: f.write_checkpoint(alpha, "alpha-{}".format(it), 0, append=True) print('DEBUG: written step ', it) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) # if size == 1: # plt.figure() # dolfin.plot(alpha, marker='o') # plt.savefig(os.path.join(outdir, "alpha-{}.png".format(it))) # plt.figure() # dolfin.plot(u, marker='o') # plt.savefig(os.path.join(outdir, "u-{}.png".format(it))) # plt.clf() if not stable and parameters['experiment']['break-if-unstable']: print('Unstable state, breaking', parameters['experiment']['break-if-unstable']) break # print(time_data_pd) print() # print(time_data_pd['stable']) print('Output in: ' + outdir) # # solve optimal profile # # Alternate minimisation solver # beta = dolfin.TestFunction(V_alpha) # dalpha = dolfin.TrialFunction(V_alpha) # F = (ell*alpha.dx(0)*alpha.dx(0) + w/ell*alpha)*dx # dF = dolfin.derivative(F,alpha,beta); ddF = dolfin.derivative(dF,alpha,dalpha) # # bcs_u = [dolfin.DirichletBC(V_u, dolfin.Constant(0.), 'on_boundary')] alpha = dolfin.Function(V_alpha) u = dolfin.Function(V_u) bcs_alpha = [ dolfin.DirichletBC(V_alpha, dolfin.Constant(1.), right), dolfin.DirichletBC(V_alpha, dolfin.Constant(0.), left) ] solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [[], bcs_alpha], parameters=parameters['alt_min']) solver.solve() print('DEBUG: h1 norm alpha profile {}'.format(dolfin.norm(alpha, 'h1'))) # ub = dolfin.interpolate(dolfin.Constant(1.), V_alpha); lb = dolfin.interpolate(dolfin.Constant(0.), V_alpha) # profile = dolfin.NonlinearVariationalProblem(dF, alpha, bcs_alpha, J = ddF) # profile.set_bounds(lb, ub) # solver_nl = dolfin.NonlinearVariationalSolver(profile) # snes_solver_parameters_bounds = {"nonlinear_solver": "snes", # "snes_solver": {"linear_solver": "cg", # "maximum_iterations": 100, # "report": True, # "line_search": "basic", # "method":"vinewtonrsls", # "absolute_tolerance":1e-6, # "relative_tolerance":1e-6, # "solution_tolerance":1e-6}} # solver_nl.parameters.update(snes_solver_parameters_bounds) # solver_nl.solve() xs = np.linspace(-Lx / 2., Lx / 2., 100) profile = np.array([alpha(x) for x in xs]) plt.figure() plt.plot(xs, profile, marker='o') # plt.plot(xs, np.array([u(x) for x in xs])) plt.savefig(os.path.join(outdir, 'profile.pdf')) # import pdb; pdb.set_trace() return time_data_pd, outdir
def traction_test(ell=0.05, ell_e=.1, degree=1, n=3, nu=0., load_min=0, load_max=2, loads=None, nsteps=20, Lx=1., Ly=0.1, outdir="outdir", postfix='', savelag=1, sigma_D0=1., periodic=False, continuation=False, checkstability=True, configString='', test=True): # constants # ell = ell Lx = Lx load_min = load_min load_max = load_max nsteps = nsteps outdir = outdir loads = loads savelag = 1 nu = dolfin.Constant(nu) ell = dolfin.Constant(ell) ell_e = ell_e E = dolfin.Constant(1.0) K = E.values()[0] / ell_e**2. sigma_D0 = E n = n # h = ell.values()[0]/n h = max(ell.values()[0] / n, .005) cell_size = h continuation = continuation isPeriodic = periodic config = json.loads(configString) if configString != '' else '' cmd_parameters = { 'material': { "ell": ell.values()[0], "ell_e": ell_e, "K": K, "E": E.values()[0], "nu": nu.values()[0], "sigma_D0": sigma_D0.values()[0] }, 'geometry': { 'Lx': Lx, 'Ly': Ly, 'n': n, }, 'experiment': { 'periodic': isPeriodic, 'signature': '' }, 'stability': { 'checkstability': checkstability, 'continuation': continuation }, 'time_stepping': { 'load_min': load_min, 'load_max': load_max, 'nsteps': nsteps, 'outdir': outdir, 'postfix': postfix, 'savelag': savelag }, 'alt_min': {}, "code": {} } # -------------------- for par in parameters: parameters[par].update(cmd_parameters[par]) if config: # import pdb; pdb.set_trace() for par in config: parameters[par].update(config[par]) # else: # parameters['material']['ell_e'] = # import pdb; pdb.set_trace() Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] ell = parameters['material']['ell'] ell_e = parameters['material']['ell_e'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) fname = "film" print(BASE_DIR) os.path.isfile(fname) signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() print('Signature is: ' + signature) # if parameters['experiment']['test'] == True: outdir += '-{}'.format(cmd_parameters['time_stepping']['postfix']) # else: outdir += '-{}{}'.format(signature, cmd_parameters['time_stepping']['postfix']) parameters['time_stepping']['outdir'] = outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ' + outdir) with open(os.path.join(outdir, 'rerun.sh'), 'w') as f: configuration = deepcopy(parameters) configuration['time_stepping'].pop('outdir') str(configuration).replace("\'True\'", "True").replace("\'False\'", "False") rerun_cmd = 'python3 {} --config="{}"'.format( os.path.basename(__file__), configuration) f.write(rerun_cmd) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) with open(os.path.join(outdir, 'signature.md5'), 'w') as f: f.write(signature) print(parameters) # ------------------ geometry_parameters = parameters['geometry'] geom_signature = hashlib.md5( str(geometry_parameters).encode('utf-8')).hexdigest() meshfile = "%s/meshes/circle-%s.xml" % (BASE_DIR, geom_signature) # cmd_parameters['experiment']['signature']=signature meshsize = parameters['material']['ell'] / parameters['geometry']['n'] d = { 'rad': parameters['geometry']['Lx'], 'Ly': parameters['geometry']['Ly'], 'meshsize': meshsize } if os.path.isfile(meshfile): print("Meshfile %s exists" % meshfile) mesh = dolfin.Mesh("meshes/circle-%s.xml" % (geom_signature)) else: print("Creating meshfile: %s" % meshfile) print("DEBUG: parameters: %s" % parameters['geometry']) mesh_template = open('templates/circle_template.geo') src = Template(mesh_template.read()) geofile = src.substitute(d) if MPI.rank(MPI.comm_world) == 0: with open("meshes/circle-%s" % geom_signature + ".geo", 'w') as f: f.write(geofile) cmd1 = 'gmsh meshes/circle-{}.geo -2 -o meshes/circle-{}.msh'.format( geom_signature, geom_signature) cmd2 = 'dolfin-convert -i gmsh meshes/circle-{}.msh meshes/circle-{}.xml'.format( geom_signature, geom_signature) print( 'Unable to handle mesh generation at the moment, please generate the mesh and test again.' ) print(cmd1) print(cmd2) sys.exit() print(check_output([cmd1], shell=True) ) # run in shell mode in case you are not run in terminal Popen([cmd2], stdout=PIPE, shell=True).communicate() mesh = Mesh('meshes/circle-{}.xml'.format(geom_signature)) mesh_xdmf = XDMFFile("meshes/circle-%s.xdmf" % (geom_signature)) mesh_xdmf.write(mesh) # with pygmsh.geo.Geometry() as geom: # circle = geom.add_circle( # [0.0, 0.0, 0.0], # 1.0, # mesh_size=0.1, # num_sections=4, # # If compound==False, the section borders have to be points of the # # discretization. If using a compound circle, they don't; gmsh can # # choose by itself where to point the circle points. # compound=True, # ) # geom.add_physical(circle.plane_surface, "disk") # # # mesh = geom.generate_mesh() # mesh.write("out.xdmf") # mesh.write("out.xml") # geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) # mesh = mshr.generate_mesh(geom, n * int(float(Lx / ell))) print(meshfile) mesh_xdmf = dolfin.XDMFFile("meshes/%s-%s.xdmf" % (fname, geom_signature)) mesh_xdmf.write(mesh) if rank == 0: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") bcs_alpha = [] # Rectangle # bcs_u = [DirichletBC(V_u, Constant((0., 0)), '(near(x[0], %f) or near(x[0], %f))'%(-Lx/2., Lx/2.))] # Circle bcs_u = [DirichletBC(V_u, Constant((0., 0.)), 'on_boundary')] state = [u, alpha] Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) ds = dolfin.Measure("ds") # Files for output file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_con = dolfin.XDMFFile(os.path.join(outdir, "continuation.xdmf")) file_bif = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) for f in [file_out, file_eig, file_con, file_bif]: f.parameters["functions_share_mesh"] = True f.parameters["flush_output"] = True # Problem foundation_density = 1. / 2. * 1. / ell_e**2. * dot(u, u) model = DamagePrestrainedElasticityModel( state, E, nu, ell, sigma_D0, user_functional=foundation_density, eps0t=Expression([['t', 0.], [0., 't']], t=0., degree=0)) # import pdb; pdb.set_trace() model.dx = dx model.ds = ds energy = model.total_energy_density(u, alpha) * dx # Alternate minimization solver solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [bcs_u, bcs_alpha], parameters=parameters['alt_min']) rP = model.rP(u, alpha, v, beta) * dx + 1 / ell_e**2. * dot(v, v) * dx rN = model.rN(u, alpha, beta) * dx # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability']) stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters=parameters['stability'], rayleigh=[rP, rN]) load_steps = np.linspace(load_min, load_max, parameters['time_stepping']['nsteps']) if loads: load_steps = loads time_data = [] linesearch = LineSearch(energy, [u, alpha]) alpha_old = dolfin.Function(alpha.function_space()) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) for it, load in enumerate(load_steps): model.eps0t.t = load alpha_old.assign(alpha) ColorPrint.print_warn('Solving load t = {:.2f}'.format(load)) # First order stability conditions (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass( 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 print('lmbda min', lmbda_min_prev) print('mineig', mineig) Deltav = (mineig - lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav) * (lmbda_min_prev + dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes print('About to bifurcate load ', load, 'step', it) bifurcation_loads.append(load) print('DEBUG: decide what to do') # save_current_bifurcation = True bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. if stable: solver.update() else: # Continuation iteration = 1 while stable == False: # linesearch perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta h_opt, (hmin, hmax), energy_perturbations = linesearch.search( [u, alpha, alpha_old], perturbation_v, perturbation_beta) if h_opt != 0: save_current_bifurcation = True alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) # admissible uval = u.vector()[:] + h_opt * perturbation_v.vector()[:] aval = alpha.vector( )[:] + h_opt * perturbation_beta.vector()[:] u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() # import pdb; pdb.set_trace() (time_data_i, am_iter) = solver.solve() (stable, negev) = stability.solve(alpha_old) ColorPrint.print_pass( ' Continuation iteration {}, current state is{}stable' .format(iteration, ' ' if stable else ' un')) iteration += 1 else: # warn ColorPrint.print_warn( 'Found zero increment, we are stuck in the matrix') ColorPrint.print_warn('Continuing load program') break solver.update() # stable == True time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha) * dx) time_data_i["foundation_energy"] = dolfin.assemble( 1. / 2. * 1 / ell_e**2. * dot(u, u) * dx) time_data_i["membrane_energy"] = dolfin.assemble( model.elastic_energy_density(model.eps(u), alpha) * dx) time_data_i["elastic_energy"] = time_data_i[ "membrane_energy"] + time_data_i["foundation_energy"] time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev _sigma = model.stress(model.eps(u), alpha) e1 = dolfin.Constant([1, 0]) _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) time_data_i["sigma"] = 1 / Ly * dolfin.assemble(_snn * model.ds(1)) time_data_i["S(alpha)"] = dolfin.assemble(1. / (model.a(alpha)) * model.dx) time_data_i["A(alpha)"] = dolfin.assemble((model.a(alpha)) * model.dx) time_data_i["avg_alpha"] = 1 / dolfin.assemble( dolfin.project(Constant(1.), V_alpha) * model.dx) * dolfin.assemble(alpha * model.dx) ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if np.mod(it, savelag) == 0: with file_out as f: f.write(alpha, load) f.write(u, load) # with file_out as f: f.write_checkpoint(alpha, "alpha-{}".format(it), 0, append=True) print('DEBUG: written step ', it) if save_current_bifurcation: # modes = np.where(stability.eigs < 0)[0] time_data_i['h_opt'] = h_opt time_data_i['max_h'] = hmax time_data_i['min_h'] = hmin with file_bif as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) print('DEBUG: irrev ', alpha.vector() - alpha_old.vector()) file.write_checkpoint(beta0v, 'beta0', 0, append=True) file.write_checkpoint(alpha_bif_old, 'alpha-old', 0, append=True) file.write_checkpoint(alpha_bif, 'alpha-bif', 0, append=True) file.write_checkpoint(alpha, 'alpha', 0, append=True) np.save(os.path.join(outdir, 'energy_perturbations'), energy_perturbations, allow_pickle=True, fix_imports=True) with file_eig as file: _v = dolfin.project( dolfin.Constant(h_opt) * perturbation_v, V_u) _beta = dolfin.project( dolfin.Constant(h_opt) * perturbation_beta, V_alpha) _v.rename('perturbation displacement', 'perturbation displacement') _beta.rename('perturbation damage', 'perturbation damage') # import pdb; pdb.set_trace() f.write(_v, load) f.write(_beta, load) file.write_checkpoint(_v, 'perturbation_v', 0, append=True) file.write_checkpoint(_beta, 'perturbation_beta', 0, append=True) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) # user_postprocess_timestep(alpha, parameters, load, xresol = 100) plt.figure() dolfin.plot(alpha) plt.savefig(os.path.join(outdir, "alpha.png")) plt.figure() dolfin.plot(u, mode="displacement") plt.savefig(os.path.join(outdir, "u.png")) _nu = parameters['material']['nu'] _E = parameters['material']['E'] _w1 = parameters['material']['sigma_D0']**2. / parameters['material']['E'] tc = np.sqrt(2 * _w1 / (_E * (1. - 2. * _nu) * (1. + _nu))) if parameters['stability']['checkstability'] == 'True': pp.plot_spectrum(parameters, outdir, time_data_pd.sort_values('load'), tc) # plt.show() collect_timings(outdir, t0) print(time_data_pd) return time_data_pd
def traction_test( ell=0.1, degree=1, n=3, nu=0.0, load_min=0, load_max=2, loads=None, nsteps=20, Lx=1, Ly=0.1, outdir="outdir", savelag=1, ): # constants ell = ell Lx = Lx Ly = Ly load_min = load_min load_max = load_max nsteps = nsteps loads=loads savelag = 1 nu = dolfin.Constant(nu) ell = dolfin.Constant(ell) E0 = dolfin.Constant(1.0) sigma_D0 = E0 n = n params = { 'material': { "ell": ell.values()[0], "E": E0.values()[0], "nu": nu.values()[0], "sigma_D0": sigma_D0.values()[0]}, 'geometry': { 'Lx': Lx, 'Ly': Ly, 'n': n, }, 'load':{ 'min': load_min, 'max': load_max, 'nsteps': nsteps } } print(params) geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) nel = max(int(n * float(Lx / ell)), int(Ly/3.)) mesh = mshr.generate_mesh(geom, nel) left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) right_bottom_pt = dolfin.CompiledSubDomain("near(x[1], Lx/2.) && near(x[0],-Ly/2.)", Lx=Lx, Ly=Ly) mf = dolfin.MeshFunction("size_t", mesh, 1, 0) right.mark(mf, 1) left.mark(mf, 2) ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") state = [u, alpha] Z = dolfin.FunctionSpace(mesh, dolfin.MixedElement([u.ufl_element(),alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) ut = dolfin.Expression("t", t=0.0, degree=0) bcs_u = [dolfin.DirichletBC(V_u.sub(0), dolfin.Constant(0), left), dolfin.DirichletBC(V_u.sub(0), ut, right), dolfin.DirichletBC(V_u, (0, 0), right_bottom_pt, method="pointwise")] bcs_alpha = [] # Problem definition model = DamageElasticityModel(state, E0, nu, ell, sigma_D0) energy = model.total_energy_density(u, alpha)*dx # Alternate minimization solver solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [bcs_u, bcs_alpha], parameters = alt_min_parameters) rP = model.rP(u, alpha, v, beta)*dx rN = model.rN(u, alpha, beta)*dx stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, rayleigh=[rP, rN], parameters = stability_parameters) # Time iterations time_data = [] load_steps = np.linspace(load_min, load_max, nsteps) alpha_old = dolfin.Function(V_alpha) for it, load in enumerate(load_steps): stable = None; negev = 0; mineig = np.inf; iteration = 0 ut.t = load ColorPrint.print_pass('load: {:4f} step {:d} ell {:f}'.format(load, it, ell.values()[0])) alpha_old.assign(alpha) time_data_i, am_iter = solver.solve() solver.update() (stable, negev) = stability.solve(alpha_old) time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["# neg ev"] = negev time_data_i["elastic_energy"] = dolfin.assemble( model.elastic_energy_density(model.eps(u), alpha)*dx) time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha)*dx) time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["max alpha"] = np.max(alpha.vector()[:]) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if stable == False: break return time_data_pd
def save_json(self, content, file_path): json_dict = json.dumps(content, ensure_ascii=False, indent=4) with open(file_path, 'w', encoding='utf-8') as json_file: json_file.write(json_dict) cp.print_success(f"Write to {file_path} successfully!")
def solve(self, alpha_old): debug = False self.alpha_old = alpha_old postfix = 'seq' if size == 1 else 'mpi' locnumbcs = np.array(len(self.bc_dofs)) if debug: print(rank, ': ', 'locnumbcs', locnumbcs) numbcs = np.array(0., 'd') comm.Reduce(locnumbcs, numbcs, op=mpi4py.MPI.SUM, root=0) if debug and rank == 0: print('#bc dofs = {}'.format(int(numbcs))) if not np.all(self.alpha.vector()[:] >= self.alpha_old.vector()[:]): pd = np.where( self.alpha.vector()[:] - self.alpha_old.vector()[:] < 0)[0] ColorPrint.print_warn( 'Pointwise irreversibility issues on dofs {}'.format(pd)) ColorPrint.print_warn( 'diff = {}'.format(self.alpha.vector()[pd] - self.alpha_old.vector()[pd])) ColorPrint.print_warn('Continuing') self.assigner.assign(self.z_old, [self.u_zero, self.alpha_old]) self.assigner.assign(self.z, [self.u_zero, self.alpha]) if self.is_elastic(self.z, self.z_old): ColorPrint.print_pass('Current state: elastic') self.stable = True self.negev = np.nan return self.stable, 0 else: ColorPrint.print_pass('Current state: not elastic') inactive_dofs = self.get_inactive_set() self.inactive_set = inactive_dofs free_dofs = list(sorted(inactive_dofs - self.bc_dofs)) index_set = petsc4py.PETSc.IS() index_set.createGeneral(free_dofs) if hasattr(self, 'rP') and hasattr(self, 'rN'): self.H2 = self.rP - self.rN if hasattr(self, 'H2'): ColorPrint.print_pass('Inertia: Using user-provided Hessian') self.H_reduced = self.reduce_Hessian(self.H2, restricted_dofs_is=index_set) else: ColorPrint.print_pass('Inertia: Using computed Hessian') self.H_reduced = self.reduce_Hessian(self.H, restricted_dofs_is=index_set) self.pc_setup() # import pdb; pdb.set_trace() negev = self.get_inertia(self.H_reduced) # if negev > 0: if True: eigs = [] # solve full eigenvalue problem eigen_tol = self.parameters['eig_rtol'] if hasattr(self, 'H2'): ColorPrint.print_pass('Full eig: Using user-provided Hessian') ColorPrint.print_pass('Norm provided {}'.format( dolfin.assemble(self.H2).norm('frobenius'))) eigen = EigenSolver(self.H2, self.z, restricted_dofs_is=index_set, slepc_options={ 'eps_max_it': 600, 'eps_tol': eigen_tol }) else: ColorPrint.print_pass('Full eig: Using computed Hessian') eigen = EigenSolver(self.H, self.z, restricted_dofs_is=index_set, slepc_options={ 'eps_max_it': 600, 'eps_tol': eigen_tol }) ColorPrint.print_pass('Norm computed {}'.format( dolfin.assemble(self.H).norm('frobenius'))) self.computed.append(dolfin.assemble(self.H).norm('frobenius')) if hasattr(self, 'H2'): self.provided.append( dolfin.assemble(self.H2).norm('frobenius')) maxmodes = self.parameters['maxmodes'] nconv, it = eigen.solve(min(maxmodes, negev + 7)) if nconv == 0: ColorPrint.print_warn('Eigensolver did not converge') self.stable = negev <= 0 self.eigs = [] self.mineig = np.nan return (self.stable, int(negev)) eigs = eigen.get_eigenvalues(nconv) negconv = sum(eigs[:, 0] < 0) # sanity check if nconv and negconv != negev: ColorPrint.print_bold( 'eigen solver found {} negative evs '.format(negconv)) if nconv == 0 and negev > 0: ColorPrint.print_bold( 'Full eigensolver did not converge but inertia yields {} neg eigen' .format(negev)) return # eigen.save_eigenvectors(nconv) if nconv > 0: ColorPrint.print_pass('') ColorPrint.print_pass("i k err ") ColorPrint.print_pass("---------------------------") for (i, k) in enumerate(eigs): ColorPrint.print_pass("%d %12e %12e" % (i, k[0], k[1])) ColorPrint.print_pass('') linsearch = [] if negconv > 0: for n in range(negconv) if negconv < maxmodes else range( maxmodes): ColorPrint.print_pass('Perturbation mode {}'.format(n)) eig, u_r, u_im, err = eigen.get_eigenpair(n) err2 = eigen.E.computeError(0, SLEPc.EPS.ErrorType.ABSOLUTE) v_n, beta_n = u_r.split(deepcopy=True) # print(rank, [self.is_compatible(bc, u_r, homogeneous = True) for bc in self.bcs_Z]) if debug and size == 1: plt.clf() plt.colorbar(dolfin.plot(dot(v_n, v_n)**(.5))) plt.savefig('data/vn-{}-{}.pdf'.format(rank, n)) self.normalise_eigen(v_n, beta_n, mode='max') beta_n = self.project(beta_n, mode=self.parameters['projection']) eig, u_r, u_im, err = eigen.get_eigenpair(n) order = self.parameters['order'] # h, en_diff, interval, energy = self.linesearch(v_n, beta_n, order, n) # linsearch.append({'n': n, 'lambda_n': eig.real,'hstar': h, 'en_diff': en_diff, # 'v_n': v_n, 'beta_n': beta_n, 'order': order, # 'interval': interval, 'energy': energy}) linsearch.append({ 'n': n, 'lambda_n': eig.real, 'v_n': v_n, 'beta_n': beta_n }) eig, u_r, u_im, err = eigen.get_eigenpair(0) self.eigs = eigs[:, 0] self.mineig = eig.real # self.stable = negev <= 0 # based on inertia self.negev = negev # based on inertia self.linsearch = linsearch if eigs[0, 0] < 0: self.perturbation_v = linsearch[0]['v_n'] self.perturbation_beta = linsearch[0]['beta_n'] # self.hstar = linsearch[0]['hstar'] # self.en_diff = linsearch[0]['en_diff'] self.eigendata = linsearch self.i += 1 print('*** negev ', negev) print('*** negev unstable ', negev < 0) print('*** mineig stable ', eig.real > 0) self.stable = eig.real > 0 # based on eigenvalue return (self.stable, int(negev))
for ell in ell_list: # tstab = 1./ell*4*np.pi/3.**(3./2.) eps = .3 ell_r = ell*np.sqrt(2) # *np.sqrt(2) tstab = t_stab(ell_r, 2) tbif = t_bif(ell_r, 2) print('tstab, tbif', tstab, tbif) # sys.exit(//z) # tstab = 1. lmin = tstab - 1. # load_min = load_min if lmin > 0. else 0. load_min = lmin if lmin > 0. else 0. load_max = tstab + 1. # loads = [tstab-2*eps, tstab+2*eps] ColorPrint.print_info('Solving ell {}'.format(ell)) ColorPrint.print_info('Load: [{} {}]'.format(load_min, load_max)) ColorPrint.print_info('stab limit: {} '.format(tstab)) ColorPrint.print_info('uniq limit: {} '.format(tbif)) try: traction_test( ell=ell, load_min=load_min, load_max=load_max, # loads = loads, nsteps=30, nu=0., n=10, # Lx=Lx, Ly=.05, # outdir='../output/parametric-traction-plane-stress/ell-{:2f}'.format(ell),
def linesearch(self, v_n, beta_n, m=3, mode=0): debug = False en0 = dolfin.assemble(self.energy) _u = self._u _alpha = self._alpha _u[:] = self.u.vector()[:] _alpha[:] = self.alpha.vector()[:] one = max(1., max(self.alpha.vector()[:])) if hasattr(self, 'bcs') and len(self.bcs[0]) > 0: assert np.all([self.is_compatible(bc, v_n, homogeneous = True) for bc in self.bcs[0]]), \ 'displacement test field is not kinematically admissible' # positive part mask = beta_n.vector()[:] > 0. hp2 = (one - self.alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [np.inf] hp1 = (self.alpha_old.vector()[mask] - self.alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [-np.inf] hp = (max(hp1), min(hp2)) # negative part mask = beta_n.vector()[:] < 0. hn2 = (one - self.alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [-np.inf] hn1 = (self.alpha_old.vector()[mask] - self.alpha.vector()[mask]) / beta_n.vector()[mask] if len( np.where(mask == True)[0]) > 0 else [np.inf] hn = (max(hn2), min(hn1)) hmax = np.array(np.min([hp[1], hn[1]])) hmin = np.array(np.max([hp[0], hn[0]])) hmax_glob = np.array(0.0, 'd') hmin_glob = np.array(0.0, 'd') comm.Allreduce(hmax, hmax_glob, op=mpi4py.MPI.MIN) comm.Allreduce(hmin, hmin_glob, op=mpi4py.MPI.MAX) self.hmax = float(hmax_glob) self.hmin = float(hmin_glob) if self.hmin > 0: ColorPrint.print_warn('Line search troubles: found hmin>0') # import pdb; pdb.set_trace() return 0., np.nan, (0., 0.), 0. if self.hmax == 0 and self.hmin == 0: ColorPrint.print_warn('Line search failed: found zero step size') # import pdb; pdb.set_trace() return 0., np.nan, (0., 0.), 0. if self.hmax < self.hmin: ColorPrint.print_warn( 'Line search failed: optimal h* not admissible') # import pdb; pdb.set_trace() return 0., np.nan, (0., 0.), 0. # get next perturbation mode en = [] htest = np.linspace(self.hmin, self.hmax, m + 1) for h in htest: uval = _u[:] + h * v_n.vector()[:] aval = _alpha[:] + h * beta_n.vector()[:] if not np.all(aval - self.alpha_old.vector()[:] + dolfin.DOLFIN_EPS_LARGE >= 0.): print( 'damage test field doesn\'t verify sharp irrev from below') import pdb pdb.set_trace() if not np.all(aval <= one): print('damage test field doesn\'t verify irrev from above') import pdb pdb.set_trace() self.u.vector()[:] = uval self.alpha.vector()[:] = aval en.append(dolfin.assemble(self.energy) - en0) if debug and size == 1: ax2.plot(xs, [self.alpha(x, 0) for x in xs], label='$\\alpha+h \\beta_{{{}}}$, h={:.3f}'.format( mode, h), lw=.5, c='C1' if h > 0 else 'C4') z = np.polyfit(htest, en, m) p = np.poly1d(z) if m == 2: ColorPrint.print_info('Line search using quadratic interpolation') hstar = -z[1] / (2 * z[0]) else: ColorPrint.print_info( 'Line search using polynomial interpolation (order {})'.format( m)) h = np.linspace(self.hmin, self.hmax, 100) hstar = h[np.argmin(p(h))] if hstar < self.hmin or hstar > self.hmax: ColorPrint.print_warn( 'Line search failed, h*={:3e} not in feasible interval'.format( hstar)) return 0., np.nan ColorPrint.print_info( 'Line search h* = {:3f} in ({:.3f}, {:.3f}), h*/hmax {:3f}\ '.format(hstar, self.hmin, self.hmax, hstar / self.hmax)) ColorPrint.print_info('Line search approx =\n {}'.format(p)) ColorPrint.print_info('h in ({:.5f},{:.5f})'.format( self.hmin, self.hmax)) ColorPrint.print_warn( 'Line search estimate, relative energy variation={:.5f}%'.format( (p(hstar)) / en0 * 100)) # restore solution self.u.vector()[:] = _u[:] self.alpha.vector()[:] = _alpha[:] return hstar, p(hstar) / en0, (self.hmin, self.hmax), en
def run(self): outdir = self.parameters['outdir'] savelag = self.parameters['savelag'] solver = self.solver stability = self.stability alpha = solver.alpha u = solver.u load_steps = self.load_steps alpha_old = Function(alpha.function_space()) self.time_data_i = [] stable = None; negev = -1; mineig = np.inf; iteration = 0 diff = alpha.copy(deepcopy=True) for it, load in enumerate(load_steps): self.load_param.t = load alpha_old.assign(alpha) print('') ColorPrint.print_warn('Solving load = {:.2f}'.format(load)) self.time_data_i, am_iter = solver.solve() diff.vector()[:] = alpha.vector() - alpha_old.vector() try: assert all(alpha.vector()[:]>=alpha_old.vector()[:]) except AssertionError: print('check alpha.vector()[:]>=alpha_old.vector()') try: assert all(solver.problem_alpha.lb.vector()[:]==alpha_old.vector()[:]) except AssertionError: print('check all(solver.problem_alpha.lb.vector()[:]==alpha_old.vector()[:])') if bool(strtobool(str(stability.parameters['checkstability']))): (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass('Current state is{}stable'.format(' ' if stable else ' not ')) if hasattr(stability, 'eigs') and len(stability.eigs)>0 and min(stability.eigs)<0: pp.plot_eigenmodes(stability.eigendata, alpha, load, outdir) self.user_postprocess_stability(load) else: solver.update() alpha.copy(deepcopy = True) if stable: solver.update() elif not stable and not bool(strtobool(str(stability.parameters['continuation']))): solver.update() elif not stable and bool(strtobool(str(stability.parameters['continuation']))): while stable == False: adm_pert = np.where(np.array([e['en_diff'] for e in stability.eigendata]) < 0)[0] if len(adm_pert)==0: ColorPrint.print_warn('No admissible perturbations found') ColorPrint.print_pass('Continuing load program') break else: continuation_data = [] steepest = np.argmin([e['en_diff'] for e in stability.eigendata]) if self.parameters['perturbation_choice']=='first': mode = 0 elif self.parameters['perturbation_choice'] == 'steepest': mode = steepest elif isinstance(self.parameters['perturbation_choice'], int): mode = self.parameters['perturbation_choice'] perturbation_v = stability.eigendata[mode]['v_n'] perturbation_beta = stability.eigendata[mode]['beta_n'] hstar = stability.eigendata[mode]['hstar'] perturbation_v.rename('step displacement perturbation', 'step displacement perturbation') perturbation_beta.rename('step damage perturbation', 'step damage perturbation') ColorPrint.print_pass('Perturbation choice {}'.format(self.parameters['perturbation_choice'])) ColorPrint.print_pass('Perturbing current state with mode {} Delta E={:.5%} (estimated)'.format(mode, stability.eigendata[mode]['en_diff'])) ColorPrint.print_pass('...... chosen mode {} vs. steepest {} Delta E={:.5%} (estimated)'.format(mode, steepest, stability.eigendata[mode]['en_diff']/stability.eigendata[steepest]['en_diff'])) ColorPrint.print_pass('...... steepest descent mode {} Delta E={:.5%} (estimated)'.format(steepest,stability.eigendata[steepest]['en_diff'])) # perturb current state self.compile_continuation_data(load, iteration, perturbed=False) solver.alpha.copy(deepcopy=True) ColorPrint.print_pass('Perturbing current state, looking for stability, iteration {}'.format(iteration)) uval = u.vector()[:] + hstar * perturbation_v.vector()[:] aval = alpha.vector()[:] + hstar * perturbation_beta.vector()[:] alpha.vector().vec().ghostUpdate() u.vector().vec().ghostUpdate() self.time_data_i, am_iter = solver.solve() if self.file_con is not None: with self.file_con as f: f.write(alpha, iteration) f.write(u, iteration) self.compile_continuation_data(load, iteration, perturbed=True) ColorPrint.print_pass('Energy diff {}, rel thhreshold {}' .format(self.continuation_data_i["total_energy_diff"]/self.continuation_data_i["total_energy"], self.stability.parameters['cont_rtol'])) continuation_data.append(self.continuation_data_i) if np.mod(it, self.parameters['savelag']) == 0: continuation_data_pd=pd.DataFrame(continuation_data) continuation_data_pd.to_json(os.path.join(outdir + "/continuation_data.json")) if self.continuation_data_i["total_energy_diff"]/self.continuation_data_i["total_energy"] < - self.stability.parameters['cont_rtol']: ColorPrint.print_pass('Updating irreversibility') solver.update() else: ColorPrint.print_pass('Threshold not met, continuing load program') break (stable, negev) = stability.solve(alpha_old) if self.file_eig is not None: with self.file_eig as f: f.write(perturbation_beta, iteration) f.write(perturbation_v, iteration) iteration += 1 time_data_pd = self.compile_time_data(load) if np.mod(it, self.parameters['savelag']) == 0: time_data_pd.to_json(os.path.join(outdir + "/time_data.json")) ColorPrint.print_pass('written data to file {}'.format(str(os.path.join(outdir + "/time_data.json")))) if self.file_out is not None: with self.file_out as f: f.write(alpha, load) f.write(u, load) pp.plot_global_data(time_data_pd,load,outdir) self.user_postprocess_timestep(load) return time_data_pd
parser.add_argument("--nu", type=float, default=0.0) parser.add_argument("--nsteps", type=int, default=30) parser.add_argument("--degree", type=int, default=2) parser.add_argument("--postfix", type=str, default='') parser.add_argument("--outdir", type=str, default=None) parser.add_argument("--savelag", type=int, default=1) parser.add_argument("--E", type=float, default=1) parser.add_argument("--parameters", type=str, default=None) parser.add_argument("--print", type=bool, default=False) parser.add_argument("--continuation", type=bool, default=False) parser.add_argument("--test", type=bool, default=True) parser.add_argument("--periodic", action='store_true') # args = parser.parse_args() args, unknown = parser.parse_known_args() if len(unknown): ColorPrint.print_warn('Unrecognised arguments:') print(unknown) ColorPrint.print_warn('continuing in 5s') sleep(5) # signature = md5().hexdigest() if args.outdir == None: args.postfix += '-cont' if args.continuation == True else '' outdir = "../output/{:s}".format('film') else: outdir = args.outdir if args.print and args.parameters is not None: cmd = '' with open(args.parameters, 'r') as params: parameters = json.load(params) for k, v in parameters.items():
def traction_test(ell=0.05, ell_e=.1, degree=1, n=3, nu=0., load_min=0, load_max=2, loads=None, nsteps=20, Lx=1., Ly=0.1, outdir="outdir", postfix='', savelag=1, sigma_D0=1., periodic=False, continuation=False, checkstability=True, configString='', test=True): # constants # ell = ell Lx = Lx load_min = load_min load_max = load_max nsteps = nsteps outdir = outdir loads = loads savelag = 1 nu = dolfin.Constant(nu) ell = dolfin.Constant(ell) ell_e = ell_e E = dolfin.Constant(1.0) K = E.values()[0] / ell_e**2. sigma_D0 = E n = n # h = ell.values()[0]/n h = max(ell.values()[0] / n, .005) cell_size = h continuation = continuation isPeriodic = periodic config = json.loads(configString) if configString != '' else '' cmd_parameters = { 'material': { "ell": ell.values()[0], "ell_e": ell_e, "K": K, "E": E.values()[0], "nu": nu.values()[0], "sigma_D0": sigma_D0.values()[0] }, 'geometry': { 'Lx': Lx, 'Ly': Ly, 'n': n, }, 'experiment': { 'test': test, 'periodic': isPeriodic, 'signature': '' }, 'stability': { 'checkstability': checkstability, 'continuation': continuation }, 'time_stepping': { 'load_min': load_min, 'load_max': load_max, 'nsteps': nsteps, 'outdir': outdir, 'postfix': postfix, 'savelag': savelag }, 'alt_min': {}, "code": {} } # -------------------- for par in parameters: parameters[par].update(cmd_parameters[par]) if config: for par in config: parameters[par].update(config[par]) # else: # parameters['material']['ell_e'] = Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] ell = parameters['material']['ell'] ell_e = parameters['material']['ell_e'] BASE_DIR = os.path.dirname(os.path.realpath(__file__)) fname = "film" print(BASE_DIR) os.path.isfile(fname) signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() if parameters['experiment']['test'] == True: outdir += '-{}'.format(cmd_parameters['time_stepping']['postfix']) else: outdir += '-{}{}'.format(signature, cmd_parameters['time_stepping']['postfix']) outdir = outdir + '-cont' parameters['time_stepping']['outdir'] = outdir Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ' + outdir) with open(os.path.join(outdir, 'rerun.sh'), 'w') as f: configuration = deepcopy(parameters) configuration['time_stepping'].pop('outdir') str(configuration).replace("\'True\'", "True").replace("\'False\'", "False") rerun_cmd = 'python3 {} --config="{}"'.format( os.path.basename(__file__), configuration) f.write(rerun_cmd) with open(os.path.join(outdir, 'parameters.pkl'), 'w') as f: json.dump(parameters, f) with open(os.path.join(outdir, 'signature.md5'), 'w') as f: f.write(signature) print(parameters) # boundary_meshfunction = dolfin.MeshFunction("size_t", mesh, "meshes/%s-%s_facet_region.xml"%(fname, signature)) # cells_meshfunction = dolfin.MeshFunction("size_t", mesh, "meshes/%s-%s_physical_region.xml"%(fname, signature)) # ------------------ geometry_parameters = parameters['geometry'] geom_signature = hashlib.md5( str(geometry_parameters).encode('utf-8')).hexdigest() meshfile = "%s/meshes/%s-%s.xml" % (BASE_DIR, fname, geom_signature) # cmd_parameters['experiment']['signature']=signature if os.path.isfile(meshfile): print("Meshfile %s exists" % meshfile) mesh = dolfin.Mesh("meshes/%s-%s.xml" % (fname, geom_signature)) else: print("Creating meshfile: %s" % meshfile) print(('DEBUG: (-Lx/2. ={} , -Ly/2.={})'.format(Lx / 2., -Ly / 2.))) geom = mshr.Rectangle(dolfin.Point(-Lx / 2., -Ly / 2.), dolfin.Point(Lx / 2., Ly / 2.)) mesh = mshr.generate_mesh(geom, n * int(float(Lx / ell))) print(meshfile) mesh_xdmf = dolfin.XDMFFile("meshes/%s-%s.xdmf" % (fname, geom_signature)) mesh_xdmf.write(mesh) if rank == 0: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) u = dolfin.Function(V_u, name="Total displacement") alpha = dolfin.Function(V_alpha, name="Damage") bcs_alpha = [] bcs_u = [ DirichletBC(V_u, Constant((0., 0)), '(near(x[0], %f) or near(x[0], %f))' % (-Lx / 2., Lx / 2.)) ] left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) bottom = dolfin.CompiledSubDomain("near(x[1],-Ly/2.)", Ly=Ly) top = dolfin.CompiledSubDomain("near(x[1],Ly/2.)", Ly=Ly) mf = dolfin.MeshFunction("size_t", mesh, 1, 0) right.mark(mf, 1) left.mark(mf, 2) bottom.mark(mf, 3) state = [u, alpha] Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) dx = dolfin.Measure("dx", metadata=form_compiler_parameters, domain=mesh) ds = dolfin.Measure("ds", subdomain_data=mf) # Files for output file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_con = dolfin.XDMFFile(os.path.join(outdir, "continuation.xdmf")) file_bif = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) for f in [file_out, file_eig, file_con, file_bif]: f.parameters["functions_share_mesh"] = True f.parameters["flush_output"] = True # Problem definition foundation_density = 1. / 2. * 1. / ell_e**2. * dot(u, u) model = DamagePrestrainedElasticityModel( state, E, nu, ell, sigma_D0, user_functional=foundation_density, eps0t=Expression([['t', 0.], [0., 0.]], t=0., degree=0)) # import pdb; .set_trace() model.dx = dx model.ds = ds energy = model.total_energy_density(u, alpha) * dx # Alternate minimization solver solver = solvers.AlternateMinimizationSolver( energy, [u, alpha], [bcs_u, bcs_alpha], parameters=parameters['alt_min']) rP = model.rP(u, alpha, v, beta) * dx + 1 / ell_e**2. * dot(v, v) * dx rN = model.rN(u, alpha, beta) * dx stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters=parameters['stability']) # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability'], rayleigh=[rP, rN]) # if isPeriodic: # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, # parameters = stability_parameters, # constrained_domain = PeriodicBoundary(Lx)) # else: # stability = StabilitySolver(mesh, energy, [u, alpha], [bcs_u, bcs_alpha], z, parameters = parameters['stability']) load_steps = np.linspace(load_min, load_max, parameters['time_stepping']['nsteps']) if loads: load_steps = loads time_data = [] linesearch = LineSearch(energy, [u, alpha]) alpha_old = dolfin.Function(alpha.function_space()) lmbda_min_prev = 0.000001 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_count = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] tot_energy = model.elastic_energy_density(model.eps(u), alpha)*dx + \ 1./2.*1/ell_e**2. * dot(u, u)*dx + \ model.damage_dissipation_density(alpha)*dx cont_atol = 1e-3 for it, load in enumerate(load_steps): model.eps0t.t = load alpha_old.assign(alpha) ColorPrint.print_warn('Solving load t = {:.2f}'.format(load)) # First order stability conditions (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.problem_alpha.lb) ColorPrint.print_pass( 'Current state is{}stable'.format(' ' if stable else ' un')) # import pdb; pdb.set_trace() mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 # print('DEBUG: lmbda min', lmbda_min_prev) # print('DEBUG: mineig', mineig) Deltav = (mineig - lmbda_min_prev) if hasattr(stability, 'eigs') else 0 if (mineig + Deltav) * (lmbda_min_prev + dolfin.DOLFIN_EPS) < 0 and not bifurcated: bifurcated = True # save 3 bif modes print('DEBUG: About to bifurcate load ', load, 'step', it) bifurcation_loads.append(load) bifurc_count += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. if stable: solver.update() else: # Continuation iteration = 1 energy_pre = dolfin.assemble(tot_energy) alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) while stable == False and iteration < 30: # linesearch perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta h_opt, (hmin, hmax), energy_perturbations = linesearch.search( [u, alpha, alpha_old], perturbation_v, perturbation_beta) # import pdb; pdb.set_trace() # if h_opt != 0: if h_opt > cont_atol: save_current_bifurcation = True # admissible uval = u.vector()[:] + h_opt * perturbation_v.vector()[:] aval = alpha.vector( )[:] + h_opt * perturbation_beta.vector()[:] u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() (time_data_i, am_iter) = solver.solve() (stable, negev) = stability.solve(alpha_old) ColorPrint.print_pass( ' Continuation iteration #{}, current state is{}stable' .format(iteration, ' ' if stable else ' un')) energy_post = dolfin.assemble(tot_energy) ener_diff = energy_post - energy_pre ColorPrint.print_warn( 'DEBUG: step {}, iteration {}, En_post - En_pre ={}'. format(it, iteration, energy_post - energy_pre)) iteration += 1 if ener_diff < 0: bifurcated = False else: # warn ColorPrint.print_warn( 'DEBUG: Found (almost) zero increment, we are stuck in the matrix' ) ColorPrint.print_warn('DEBUG: h_opt = {}'.format(h_opt)) ColorPrint.print_warn('DEBUG: Continuing load program') break solver.update() # stable == True # modes = np.where(stability.eigs < 0)[0] # with file_bif as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) # for n in range(maxmodes): # mode = dolfin.project(stability.linsearch[n]['beta_n'], V_alpha) # modename = 'beta-%d'%n # print(modename) # file.write_checkpoint(mode, modename, 0, append=True) # bifurc_count += 1 time_data_i["load"] = load time_data_i["stable"] = stable time_data_i["dissipated_energy"] = dolfin.assemble( model.damage_dissipation_density(alpha) * dx) time_data_i["foundation_energy"] = dolfin.assemble( 1. / 2. * 1 / ell_e**2. * dot(u, u) * dx) time_data_i["membrane_energy"] = dolfin.assemble( model.elastic_energy_density(model.eps(u), alpha) * dx) time_data_i["elastic_energy"] = time_data_i[ "membrane_energy"] + time_data_i["foundation_energy"] time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev # import pdb; pdb.set_trace() _sigma = model.stress(model.eps(u), alpha) e1 = dolfin.Constant([1, 0]) _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) time_data_i["sigma"] = 1 / Ly * dolfin.assemble(_snn * model.ds(1)) time_data_i["S(alpha)"] = dolfin.assemble(1. / (model.a(alpha)) * model.dx) time_data_i["A(alpha)"] = dolfin.assemble((model.a(alpha)) * model.dx) time_data_i["avg_alpha"] = dolfin.assemble(alpha * model.dx) ColorPrint.print_pass( "Time step {:.4g}: it {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"], time_data_i["alpha_error"])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) if np.mod(it, savelag) == 0: with file_out as f: f.write(alpha, load) f.write(u, load) f.write_checkpoint(alpha, "alpha-{}".format(it), 0, append=True) # with file_bif as f: print('DEBUG: written step ', it) if save_current_bifurcation: # modes = np.where(stability.eigs < 0)[0] time_data_i['h_opt'] = h_opt time_data_i['max_h'] = hmax time_data_i['min_h'] = hmin with file_bif as file: beta0v = dolfin.project(stability.perturbation_beta, V_alpha) file.write_checkpoint(beta0v, 'beta0', bifurc_count - 1, append=True) file.write_checkpoint(alpha_bif_old, 'alpha-old', bifurc_count - 1, append=True) file.write_checkpoint(alpha_bif, 'alpha-bif', bifurc_count - 1, append=True) file.write_checkpoint(alpha, 'alpha', bifurc_count - 1, append=True) np.save(os.path.join(outdir, 'energy_perturbations'), energy_perturbations, allow_pickle=True, fix_imports=True) with file_eig as file: _v = dolfin.project( dolfin.Constant(h_opt) * perturbation_v, V_u) _beta = dolfin.project( dolfin.Constant(h_opt) * perturbation_beta, V_alpha) _v.rename('perturbation displacement', 'perturbation displacement') _beta.rename('perturbation damage', 'perturbation damage') # import pdb; pdb.set_trace() f.write(_v, load) f.write(_beta, load) file.write_checkpoint(_v, 'perturbation_v', bifurc_count - 1, append=True) file.write_checkpoint(_beta, 'perturbation_beta', bifurc_count - 1, append=True) save_current_bifurcation = False time_data_pd.to_json(os.path.join(outdir, "time_data.json")) plt.figure() plt.plot(time_data_pd["load"].values(), time_data_pd["iterations"].values(), label='its') plt.semilogy() ax = plt.gca() ax2 = ax.twinx() ax2.plot(time_data_pd["load"].values(), time_data_pd["alpha_error"].values(), 'o', c='C1', label='alpha error') plt.savefig(os.path.join(outdir, 'am.pdf')) plt.legend() plt.close() # user_postprocess_timestep(alpha, parameters, load, xresol = 100) plt.figure() dolfin.plot(alpha) plt.savefig(os.path.join(outdir, "alpha.png")) plt.figure() dolfin.plot(u, mode="displacement") plt.savefig(os.path.join(outdir, "u.png")) _nu = parameters['material']['nu'] _E = parameters['material']['E'] _w1 = parameters['material']['sigma_D0']**2. / parameters['material']['E'] tc = np.sqrt(2 * _w1 / (_E * (1. - 2. * _nu) * (1. + _nu))) if parameters['stability']['checkstability'] == 'True': pp.plot_spectrum(parameters, outdir, time_data_pd.sort_values('load'), tc) # plt.show() print(time_data_pd) print() print('Output in: ' + outdir) return time_data_pd
def J(self, A, x): assemble(self.jacobian, tensor=A) if self.nullspace: ColorPrint.print_info("Removing nullspace in 1st order problem") A.set_nullspace(self.nullspace) [bc.apply(A) for bc in self.bcs]
N = N, ZETA = ZETA, Gamma = Gamma, alpha = alpha, beta = beta, MR = MR, ) (gt_E, gt_D, D, gt_T) = tg.generate() gensNames = list( str(i) for i in range(M) ) print(gensNames) C_num = D.shape[1] G_num = D.shape[0] _.print_warn( 'There is {} cells and {} mutations at {} genes in this dataset.'.format(C_num, G_num, len(gensNames)) ) # ### fill missed data # def tf(m,c): # os = len(np.where(D[:,c]==1.))*1. # zs = len(np.where(D[:,c]==0.))*1. # return 1. if np.random.rand() < os/(os+zs) else 0. # for m in range(G_num): # for c in range(C_num): # if D[m,c] == 3.: # D[m,c] = tf(m,c)
### load random data # M = 20 # N = 40 ZETA = 1 Gamma = 0.15 alpha = 0.01 beta = 0.01 MR = 0.005 prefix_dir = '../outputs/logs/' for N in CELL_RANGE: for M in np.linspace(N // 2, N, min(10, N - 1), dtype=np.int): step_num = 10 _.print_info('There is {} cells and {} mutations.'.format(N, M)) while True: # try: # with open('n{}_m{}_z{}_g{}_a{}_b{}_mr{}.txt'.format(N, M, ZETA, Gamma, alpha, beta, MR), 'w') as file: logfile = open( '{}n{}_m{}_z{}_g{}_a{}_b{}_mr{}.txt'.format( prefix_dir, N, M, ZETA, Gamma, alpha, beta, MR), 'w') logfile.write('There is {} cells and {} mutations.\n'.format(N, M)) tg = TreeGenerator( M=M, N=N, ZETA=ZETA, Gamma=Gamma, alpha=alpha, beta=beta,
def load_configuration(): with open("parameters.yaml", 'r') as stream: try: return yaml.load(stream) except yaml.YAMLError as exc: print(exc) def is_disable(parameters): if 'enable' in parameters and not parameters['enable']: _.print_plugin_disable(plugin, parameters) return True return False if __name__ == '__main__': for plugin, parameters in load_configuration().items(): if is_disable(parameters): _.print_plugin_disable(plugin, parameters) continue else: _.print_plugin(plugin, parameters) if 'enable' in parameters: del parameters['enable'] obj = find_and_load_plugin(plugin)() getattr(obj, 'run')(**parameters) obj.generate_pcap("%s.pcap" % plugin)
def search(self, state, v_n, beta_n, m=3, mode=0): # m: order of polynomial approximation # mode: index of mode, for display purposes debug = False en = [] en0 = dolfin.assemble(self.energy) u_0 = self.u_0 alpha_0 = self.alpha_0 u = state[0] alpha = state[1] alpha_old = state[2] u_0[:] = u.vector()[:] alpha_0[:] = alpha.vector()[:] (self.hmin, self.hmax) = self.admissible_interval(alpha, alpha_old, beta_n) htest = np.linspace(self.hmin, self.hmax, m + 1) for h in htest: uval = u_0[:] + h * v_n.vector()[:] aval = alpha_0[:] + h * beta_n.vector()[:] if not np.all(aval - alpha_old.vector()[:] + dolfin.DOLFIN_EPS_LARGE >= 0.): raise Exception( 'damage test field doesn\'t verify sharp irrev from below') if not np.all(aval <= self.upperbound): raise Exception( 'damage test field doesn\'t verify irrev from above') u.vector()[:] = uval alpha.vector()[:] = aval u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() en.append(dolfin.assemble(self.energy) - en0) # if debug and size == 1: # ax2.plot(xs, [self.alpha(x, 0) for x in xs], label='$\\alpha+h \\beta_{{{}}}$, h={:.3f}'.format(mode, h), lw=.5, c='C1' if h>0 else 'C4') z = np.polyfit(htest, en, m) p = np.poly1d(z) # import pdb; pdb.set_trace() if m == 2: ColorPrint.print_info('Line search using quadratic interpolation') h_opt = -z[1] / (2 * z[0]) else: ColorPrint.print_info( 'Line search using polynomial interpolation (order {})'.format( m)) h = np.linspace(self.hmin, self.hmax, 100) h_opt = h[np.argmin(p(h))] if h_opt < self.hmin or h_opt > self.hmax: ColorPrint.print_warn( 'Line search failed, h_opt={:3e} not in feasible interval'. format(h_opt)) return h_opt, self.hmin, self.hmax ColorPrint.print_info( 'Line search h_opt = {:3f} in ({:.3f}, {:.3f}), h_opt/hmax {:3f}\ '.format(h_opt, self.hmin, self.hmax, h_opt / self.hmax)) ColorPrint.print_info( 'Line search polynomial approximation =\n {}'.format(p)) ColorPrint.print_info('h in ({:.5f},{:.5f})'.format( self.hmin, self.hmax)) ColorPrint.print_warn( 'Line search estimate, relative energy variation={:.2f}%'.format( (p(h_opt)) / en0 * 100)) # restore solution u.vector()[:] = u_0[:] alpha.vector()[:] = alpha_0[:] u.vector().vec().ghostUpdate() alpha.vector().vec().ghostUpdate() # return h_opt, p(h_opt)/en0, (self.hmin, self.hmax), en return h_opt, (self.hmin, self.hmax), en
def is_disable(parameters): if 'enable' in parameters and not parameters['enable']: _.print_plugin_disable(plugin, parameters) return True return False
from utils import ColorPrint as _ font = {'weight': 'normal', 'size': 24} mpl.rc('font', **font) ### load Navin's data D = np.loadtxt('../datasets/real/dataNavin.csv', delimiter=' ') gensNames = np.loadtxt('../datasets/real/dataNavin.geneNames', dtype=np.str) D.shape C_num = D.shape[1] G_num = D.shape[0] _.print_warn( 'There is {} cells and {} mutations at {} genes in this dataset.'.format( C_num, G_num, len(gensNames))) ### fill missed data def tf(m, c): os = len(np.where(D[:, c] == 1.)) * 1. zs = len(np.where(D[:, c] == 0.)) * 1. return 1. if np.random.rand() < os / (os + zs) else 0. for m in range(G_num): for c in range(C_num): if D[m, c] == 3.: D[m, c] = tf(m, c)