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 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.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_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 numerical_test( user_parameters ): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurcation_loads = [] comm = MPI.comm_world default_parameters = getDefaultParameters() default_parameters.update(user_parameters) parameters = default_parameters parameters['code']['script'] = __file__ signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir = '../output/traction/{}-{}CPU'.format(signature, size) Path(outdir).mkdir(parents=True, exist_ok=True) log(LogLevel.INFO, 'Outdir is: '+outdir) BASE_DIR = os.path.dirname(os.path.realpath(__file__)) print(parameters['geometry']) d={'Lx': parameters['geometry']['Lx'],'Ly': parameters['geometry']['Ly'], 'h': parameters['material']['ell']/parameters['geometry']['n']} geom_signature = hashlib.md5(str(d).encode('utf-8')).hexdigest() Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] n = parameters['geometry']['n'] ell = parameters['material']['ell'] fname = os.path.join('../meshes', 'strip-{}'.format(geom_signature)) resolution = max(parameters['geometry']['n'] * Lx / ell, 5/(Ly*10)) resolution = 3 geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) mesh = mshr.generate_mesh(geom, resolution) log(LogLevel.INFO, 'Number of dofs: {}'.format(mesh.num_vertices()*(1+parameters['general']['dim']))) if size == 1: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) Lx = parameters['geometry']['Lx'] ell = parameters['material']['ell'] savelag = 1 # Function Spaces V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) L2 = dolfin.FunctionSpace(mesh, "DG", 0) u = dolfin.Function(V_u, name="Total displacement") u.rename('u', 'u') alpha = Function(V_alpha) alpha_old = dolfin.Function(alpha.function_space()) alpha.rename('alpha', 'alpha') dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': alpha} Z = dolfin.FunctionSpace(mesh, dolfin.MixedElement([u.ufl_element(),alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) 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) 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 = [] bcs = {"damage": bcs_alpha, "elastic": bcs_u} ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=parameters['compiler'], domain=mesh) ell = parameters['material']['ell'] # ----------------------- # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha) ** 2. + k_res w_1 = parameters['material']['sigma_D0'] ** 2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) eps0t=Expression([['t', 0.],[0.,'t']], t=0., degree=0) lmbda0 = parameters['material']['E'] * parameters['material']['nu'] /(1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E']/ 2. / (1.0 + parameters['material']['nu']) nu = parameters['material']['nu'] sigma0 = lmbda0 * tr(eps)*dolfin.Identity(parameters['general']['dim']) + 2*mu0*eps e1 = Constant((1., 0)) _sigma = ((1 - alpha) ** 2. + k_res)*sigma0 _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) # ------------------- ell = parameters['material']['ell'] E = parameters['material']['E'] def elastic_energy(u,alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res): a = (1 - alpha) ** 2. + k_res eps = sym(grad(u)) Wt = a*E*nu/(2*(1-nu**2.)) * tr(eps)**2. \ + a*E/(2.*(1+nu))*(inner(eps, eps)) return Wt * dx def dissipated_energy(alpha,w_1=w_1,ell=ell): return w_1 *( alpha + ell** 2.*inner(grad(alpha), grad(alpha)))*dx def total_energy(u, alpha, k_res=k_res, w_1=w_1, E=E, nu=nu, ell=ell, eps0t=eps0t): elastic_energy_ = elastic_energy(u,alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res) dissipated_energy_ = dissipated_energy(alpha,w_1=w_1,ell=ell) return elastic_energy_ + dissipated_energy_ def energy_1d(h, perturbation_v=Function(u.function_space()), perturbation_beta=Function(alpha.function_space())): return assemble(total_energy(u + float(h) * perturbation_v, alpha + float(h) * perturbation_beta)) energy = total_energy(u,alpha) def create_output(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_postproc = dolfin.XDMFFile(os.path.join(outdir, "postprocess.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile(os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True file_ealpha = dolfin.XDMFFile(os.path.join(outdir, "elapha.xdmf")) file_ealpha.parameters["functions_share_mesh"] = True file_ealpha.parameters["flush_output"] = True files = {'output': file_out, 'postproc': file_postproc, 'eigen': file_eig, 'bifurcation': file_bif, 'ealpha': file_ealpha} return files files = create_output(outdir) solver = EquilibriumAM(energy, state, bcs, parameters=parameters) stability = StabilitySolver(energy, state, bcs, parameters = parameters) linesearch = LineSearch(energy, state) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) tc = (parameters['material']['sigma_D0']/parameters['material']['E'])**(.5) _eps = 1e-3 load_steps = [0., tc-_eps, tc+_eps] time_data = [] time_data_pd = [] bifurcation_loads = [] save_current_bifurcation = False alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] save_bifurcation = 1 log(LogLevel.INFO, '{}'.format(parameters)) for step, load in enumerate(load_steps): plt.clf() mineigs = [] exhaust_modes = [] log(LogLevel.CRITICAL, '====================== STEPPING ==========================') log(LogLevel.CRITICAL, 'Solving load t = {:.2f}'.format(load)) alpha_old.assign(alpha) ut.t = load (time_data_i, am_iter) = solver.solve() # Second order stability (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.CRITICAL, 'Current state is{}stable'.format(' ' if stable else ' un')) if stable: solver.update() else: log(LogLevel.INFO, 'About to bifurcate load {:.3f} step {}'.format(load, step)) iteration = 1 mineigs.append(stability.mineig) while stable == False: log(LogLevel.INFO, 'Continuation iteration {}'.format(iteration)) iteration += 1 # plotstep() cont_data_pre = compile_continuation_data(state, energy) opt_mode = 0 perturbation_v = stability.perturbations_v[opt_mode] perturbation_beta = stability.perturbations_beta[opt_mode] (hmin, hmax) = linesearch.admissible_interval(alpha, alpha_old, perturbation_beta) hs = np.linspace(hmin, hmax, 20) energy_vals = np.array([energy_1d(h, perturbation_v, perturbation_beta) for h in hs]) h_opt = hs[np.argmin(energy_vals)] log(LogLevel.INFO, 'Computed h_opt {}'.format(h_opt)) perturbation = {'v': stability.perturbations_v[opt_mode], 'beta': stability.perturbations_beta[opt_mode], 'h': h_opt} perturbState(state, perturbation) (time_data_i, am_iter) = solver.solve(outdir) (stable, negev) = stability.solve(solver.damage.problem.lb) mineigs.append(stability.mineig) log(LogLevel.INFO, 'Continuation iteration {}, current state is{}stable'.format(iteration, ' ' if stable else ' un')) cont_data_post = compile_continuation_data(state, energy) # continuation criterion if abs(np.diff(mineigs)[-1]) > parameters['stability']['cont_rtol']: log(LogLevel.INFO, 'Continuing perturbations') else: log(LogLevel.CRITICAL, 'We are stuck in the matrix') log(LogLevel.WARNING, 'Continuing load program') break solver.update() if save_current_bifurcation: plotPerturbationData() savePerturbationData() save_current_bifurcation = False def compileTimeData(time_data_i, load): time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble(elastic_energy( u,alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res)) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * parameters['material']['ell'] ** 2. * inner(grad(alpha), grad(alpha)))*dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["sigma"] = 1/Ly * dolfin.assemble(_snn*ds(1)) log(LogLevel.INFO, "Load/time step {:.4g}: converged in iterations: {:3d}, err_alpha={:.4e}".format( time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) return time_data_i time_data.append(compileTimeData(time_data_i, load)) time_data_pd = pd.DataFrame(time_data) def outputData(): np.save(os.path.join(outdir, 'bifurcation_loads'), bifurcation_loads, allow_pickle=True, fix_imports=True) with files['output'] as file: file.write(alpha, load) file.write(u, load) with files['postproc'] as file: file.write_checkpoint(alpha, "alpha-{}".format(step), step, append = True) file.write_checkpoint(u, "u-{}".format(step), step, append = True) log(LogLevel.INFO, 'Written postprocessing step {}'.format(step)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) outputData() return time_data_pd, outdir
def numerical_test( user_parameters, ell=0.05, nu=0., ): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 bifurcation_loads = [] # Create mesh and define function space geometry_parameters = {'Lx': 1., 'Ly': .1, 'n': 5} # Define Dirichlet boundaries comm = MPI.comm_world outdir = '../test/output/test_film_firstorder' Path(outdir).mkdir(parents=True, exist_ok=True) with open('../parameters/form_compiler.yml') as f: form_compiler_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: solver_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/film.yaml') as f: material_parameters = yaml.load(f, Loader=yaml.FullLoader)['material'] with open('../parameters/loading.yaml') as f: loading_parameters = yaml.load(f, Loader=yaml.FullLoader)['loading'] with open('../parameters/stability.yaml') as f: stability_parameters = yaml.load(f, Loader=yaml.FullLoader)['stability'] Path(outdir).mkdir(parents=True, exist_ok=True) log(LogLevel.INFO, 'INFO: Outdir is: '+outdir) default_parameters = { 'code': {**code_parameters}, 'compiler': {**form_compiler_parameters}, 'geometry': {**geometry_parameters}, 'loading': {**loading_parameters}, 'material': {**material_parameters}, 'solver':{**solver_parameters}, 'stability': {**stability_parameters}, } default_parameters.update(user_parameters) # FIXME: Not nice parameters = default_parameters Ly = parameters['geometry']['Ly'] Lx = parameters['geometry']['Lx'] geom = mshr.Rectangle(dolfin.Point(-Lx/2., -Ly/2.), dolfin.Point(Lx/2., Ly/2.)) import pdb; pdb.set_trace() # resolution = max(geometry_parameters['n'] * Lx / ell, 1/(Ly*10)) resolution = max(geometry_parameters['n'] * Lx / ell, 5/(Ly*10)) resolution = 150 mesh = mshr.generate_mesh(geom, resolution) if size == 1: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] ell = parameters['material']['ell'] # import pdb; pdb.set_trace() savelag = 1 left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) 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) 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") u.rename('u', 'u') alpha = Function(V_alpha) alpha_old = dolfin.Function(alpha.function_space()) alpha.rename('alpha', 'alpha') dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': 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, dolfin.Constant((0,0)), left), # dolfin.DirichletBC(V_u, dolfin.Constant((0,0)), right), # dolfin.DirichletBC(V_u, (0, 0), left_bottom_pt, method="pointwise") # ] # bcs_u = [dolfin.DirichletBC(V_u, dolfin.Constant((0,0)), 'on_boundary')] bcs_u = [dolfin.DirichletBC(V_u.sub(0), dolfin.Constant(0), left), dolfin.DirichletBC(V_u.sub(0), dolfin.Constant(0), right), ] # bcs_alpha_l = DirichletBC(V_alpha, Constant(0.0), left) # bcs_alpha_r = DirichletBC(V_alpha, Constant(0.0), right) # bcs_alpha =[bcs_alpha_l, bcs_alpha_r] bcs_alpha = [] bcs = {"damage": bcs_alpha, "elastic": bcs_u} # import pdb; pdb.set_trace() ell = parameters['material']['ell'] # Problem definition # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha) ** 2. + k_res w_1 = parameters['material']['sigma_D0'] ** 2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) eps0t=Expression([['t', 0.],[0.,'t']], t=0., degree=0) lmbda0 = parameters['material']['E'] * parameters['material']['nu'] /(1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E']/ 2. / (1.0 + parameters['material']['nu']) nu = parameters['material']['nu'] Wt = a*parameters['material']['E']*nu/(2*(1-nu**2.)) * tr(eps-eps0t)**2. \ + a*parameters['material']['E']*(inner(eps-eps0t, eps-eps0t)/(2.*(1+nu))) \ + 1./2.*1./parameters['material']['ell_e']**2.*dot(u, u) energy = Wt * dx + w_1 *( alpha + parameters['material']['ell']** 2.*inner(grad(alpha), grad(alpha)))*dx # import pdb; pdb.set_trace() file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.parameters["flush_output"] = True file_postproc = dolfin.XDMFFile(os.path.join(outdir, "postprocess.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile(os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True solver = EquilibriumSolver(energy, state, bcs, parameters=parameters['solver']) stability = StabilitySolver(energy, state, bcs, parameters = parameters['stability']) # stability = StabilitySolver(energy, state, bcs, parameters = parameters['stability'], rayleigh= [rP, rN]) linesearch = LineSearch(energy, state) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] perturb = False for step, load in enumerate(load_steps): log(LogLevel.CRITICAL, '====================== STEPPING ==========================') log(LogLevel.CRITICAL, 'CRITICAL: Solving load t = {:.2f}'.format(load)) alpha_old.assign(alpha) eps0t.t = load (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.CRITICAL, 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 log(LogLevel.INFO, 'INFO: lmbda min {}'.format(lmbda_min_prev)) log(LogLevel.INFO, 'INFO: mineig {}'.format(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 log(LogLevel.INFO, 'INFO: About to bifurcate load {} step {}'.format(load, step)) 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. # we postpone the update after the stability check # solver.update() log(LogLevel.INFO,' Current state is{}stable'.format(' ' if stable else ' un')) if not stable: save_current_bifurcation = True perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta h_opt, (hmin, hmax), energy_perturbations = linesearch.search( {'u':u, 'alpha':alpha, 'alpha_old': alpha_old}, perturbation_v, perturbation_beta) # else: # # Continuation # iteration = 1 # while stable == False: # # linesearch # save_current_bifurcation = True # cont_data_pre = compile_continuation_data(state, energy) # perturbation_v = stability.perturbation_v # perturbation_beta = stability.perturbation_beta # # import pdb; pdb.set_trace() # h_opt, (hmin, hmax), energy_perturbations = linesearch.search( # {'u':u, 'alpha':alpha, 'alpha_old': alpha_old}, # perturbation_v, perturbation_beta) # stable = True # if h_opt != 0: # log(LogLevel.INFO, ' Bifurcarting') # 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(solver.damage.problem.lb) # log(LogLevel.INFO, ' Continuation iteration {}, current state is{}stable'.format(iteration, ' ' if stable else ' un')) # iteration += 1 # cont_data_post = compile_continuation_data(state, energy) # # # import pdb; pdb.set_trace() # criterion = (cont_data_post['energy']-cont_data_pre['energy'])/cont_data_pre['energy'] < parameters['stability']['cont_rtol'] # log(LogLevel.INFO, 'INFO: Continuation criterion {}'.format(criterion)) # else: # # warn # log(LogLevel.WARNING, 'Found zero increment, we are stuck in the matrix') # log(LogLevel.WARNING, 'Continuing load program') # break solver.update() # 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_postproc as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) log(LogLevel.DEBUG, 'DEBUG: irrev {}'.format(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') file.write(_v, load) file.write(_beta, load) time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble( a * Wt * dx) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * material_parameters['ell'] ** 2. * inner(grad(alpha), grad(alpha)))*dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf # eps_ = variable(eps) # import pdb; pdb.set_trace() # sigma = derivative( 1./2.* lmbda0 * tr(eps-eps0t)**2. + mu0 * inner(eps-eps0t, eps-eps0t), eps, eps_) # snn = dolfin.dot(dolfin.dot(sigma, e1), e1) # time_data_i["sigma"] = 1/parameters['geometry']['Ly'] * dolfin.assemble(snn*ds(1)) log(LogLevel.INFO, "Load/time step {:.4g}: converged in iterations: {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) with file_out as file: file.write(alpha, load) file.write(u, load) with file_postproc as file: file.write_checkpoint(alpha, "alpha-{}".format(step), step, append = True) file.write_checkpoint(u, "u-{}".format(step), step, append = True) log(LogLevel.INFO, 'INFO: written postprocessing step {}'.format(step)) spacetime.append(get_trace(alpha)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) _spacetime = pd.DataFrame(spacetime) spacetime = _spacetime.fillna(0) mat = np.matrix(spacetime) plt.imshow(mat, cmap = 'Greys', vmin = 0., vmax = 1., aspect=.1) plt.colorbar() def format_space(x, pos, xresol = 100): return '$%1.1f$'%((-x+xresol/2)/xresol) def format_time(t, pos, xresol = 100): return '$%1.1f$'%((t-parameters['loading']['load_min'])/parameters['loading']['n_steps']*parameters['loading']['load_max']) from matplotlib.ticker import FuncFormatter, MaxNLocator ax = plt.gca() ax.yaxis.set_major_formatter(FuncFormatter(format_space)) ax.xaxis.set_major_formatter(FuncFormatter(format_time)) plt.xlabel('$x$') plt.ylabel('$t$') plt.savefig(os.path.join(outdir, "spacetime.pdf".format(load)), bbox_inches="tight") plt.clf() spacetime.to_json(os.path.join(outdir + "/spacetime.json")) from matplotlib.ticker import FuncFormatter, MaxNLocator plot(alpha) plt.savefig(os.path.join(outdir, 'alpha.pdf')) log(LogLevel.INFO, "Saved figure: {}".format(os.path.join(outdir, 'alpha.pdf'))) # import pdb; pdb.set_trace() xs = np.linspace(-Lx/2., Lx/2., 300) alpha.set_allow_extrapolation(True) u.set_allow_extrapolation(True) plt.figure() plt.plot(xs, np.array([alpha(x, 0) for x in xs]), marker='o', label=r'$\alpha(x)$') plt.plot(xs, np.array([u(x, 0) for x in xs]), label=r'u(x, 0)') plt.legend() # plt.ylim(0., 1.) plt.savefig(os.path.join(outdir, 'profile.pdf')) return time_data_pd, outdir
def numerical_test( user_parameters, ell=0.05, nu=0., ): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 bifurcation_loads = [] # Create mesh and define function space geometry_parameters = {'Lx': 1., 'Ly': .1, 'n': 5} # Define Dirichlet boundaries outdir = '../test/output/test_secondorderevo' Path(outdir).mkdir(parents=True, exist_ok=True) with open('../parameters/form_compiler.yml') as f: form_compiler_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: solver_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/model1d.yaml') as f: material_parameters = yaml.load(f, Loader=yaml.FullLoader)['material'] with open('../parameters/loading.yaml') as f: loading_parameters = yaml.load(f, Loader=yaml.FullLoader)['loading'] with open('../parameters/stability.yaml') as f: stability_parameters = yaml.load(f, Loader=yaml.FullLoader)['stability'] Path(outdir).mkdir(parents=True, exist_ok=True) print('Outdir is: ' + outdir) default_parameters = { 'code': { **code_parameters }, 'compiler': { **form_compiler_parameters }, 'geometry': { **geometry_parameters }, 'loading': { **loading_parameters }, 'material': { **material_parameters }, 'solver': { **solver_parameters }, 'stability': { **stability_parameters }, } default_parameters.update(user_parameters) # FIXME: Not nice parameters = default_parameters with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] ell = parameters['material']['ell'] comm = MPI.comm_world geom = mshr.Rectangle(dolfin.Point(-Lx / 2., -Ly / 2.), dolfin.Point(Lx / 2., Ly / 2.)) # import pdb; pdb.set_trace() # resolution = max(geometry_parameters['n'] * Lx / ell, 1/(Ly*10)) resolution = max(geometry_parameters['n'] * Lx / ell, 5 / (Ly * 10)) resolution = 50 mesh = mshr.generate_mesh(geom, resolution) meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') savelag = 1 left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) 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) 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 = Function(V_alpha) dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': 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), left_bottom_pt, method="pointwise") ] bcs_alpha_l = DirichletBC(V_alpha, Constant(0.0), left) bcs_alpha_r = DirichletBC(V_alpha, Constant(0.0), right) # bcs_alpha =[bcs_alpha_l, bcs_alpha_r] bcs_alpha = [] bcs = {"damage": bcs_alpha, "elastic": bcs_u} # import pdb; pdb.set_trace() ell = parameters['material']['ell'] # Problem definition # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha)**2. + k_res w_1 = parameters['material']['sigma_D0']**2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) lmbda0 = parameters['material']['E'] * parameters['material']['nu'] / ( 1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E'] / 2. / (1.0 + parameters['material']['nu']) Wu = 1. / 2. * lmbda0 * tr(eps)**2. + mu0 * inner(eps, eps) energy = a * Wu * dx + w_1 *( alpha + \ parameters['material']['ell']** 2.*inner(grad(alpha), grad(alpha)))*dx eps_ = variable(eps) sigma = diff(a * Wu, eps_) e1 = dolfin.Constant([1, 0]) file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.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_eig = dolfin.XDMFFile(os.path.join(outdir, "modes.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True solver = EquilibriumAM(energy, state, bcs, parameters=parameters['solver']) stability = StabilitySolver(energy, state, bcs, parameters=parameters['stability']) linesearch = LineSearch(energy, state) xs = np.linspace(-parameters['geometry']['Lx'] / 2., parameters['geometry']['Lx'] / 2, 50) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) log(LogLevel.INFO, '====================== EVO ==========================') log(LogLevel.INFO, '{}'.format(parameters)) for it, load in enumerate(load_steps): log(LogLevel.CRITICAL, '====================== STEPPING ==========================') log(LogLevel.CRITICAL, 'CRITICAL: Solving load t = {:.2f}'.format(load)) ut.t = load (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.CRITICAL, 'Current state is{}stable'.format(' ' if stable else ' un')) # we postpone the update after the stability check solver.update() mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 log(LogLevel.INFO, 'INFO: lmbda min {}'.format(lmbda_min_prev)) log(LogLevel.INFO, 'INFO: mineig {}'.format(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. time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble( 1. / 2. * material_parameters['E'] * a * eps**2. * dx) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * material_parameters['ell']**2. * inner(grad(alpha), grad(alpha))) * dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf snn = dolfin.dot(dolfin.dot(sigma, e1), e1) time_data_i["sigma"] = 1 / parameters['geometry'][ 'Ly'] * dolfin.assemble(snn * ds(1)) log( LogLevel.INFO, "Load/time step {:.4g}: iteration: {:3d}, err_alpha={:.4g}".format( time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) 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) log(LogLevel.PROGRESS, 'PROGRESS: written step {}'.format(it)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) spacetime.append(get_trace(alpha)) 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_postproc as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) beta0v = dolfin.project(stability.perturbation_beta, V_alpha) log( LogLevel.DEBUG, 'DEBUG: irrev {}'.format(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) _spacetime = pd.DataFrame(spacetime) spacetime = _spacetime.fillna(0) mat = np.matrix(spacetime) plt.imshow(mat, cmap='Greys', vmin=0., vmax=1., aspect=.1) plt.colorbar() def format_space(x, pos, xresol=100): return '$%1.1f$' % ((-x + xresol / 2) / xresol) def format_time(t, pos, xresol=100): return '$%1.1f$' % ((t - parameters['loading']['load_min']) / parameters['loading']['n_steps'] * parameters['loading']['load_max']) from matplotlib.ticker import FuncFormatter, MaxNLocator ax = plt.gca() ax.yaxis.set_major_formatter(FuncFormatter(format_space)) ax.xaxis.set_major_formatter(FuncFormatter(format_time)) plt.xlabel('$x$') plt.ylabel('$t$') plt.savefig(os.path.join(outdir, "spacetime.pdf".format(load)), bbox_inches="tight") spacetime.to_json(os.path.join(outdir + "/spacetime.json")) from matplotlib.ticker import FuncFormatter, MaxNLocator plot(alpha) plt.savefig(os.path.join(outdir, 'alpha.pdf')) log(LogLevel.INFO, "Saved figure: {}".format(os.path.join(outdir, 'alpha.pdf'))) xs = np.linspace(-Lx / 2., Lx / 2., 100) profile = np.array([alpha(x, 0) for x in xs]) plt.figure() plt.plot(xs, profile, marker='o') plt.plot(xs, np.array([u(x, 0) for x in xs])) # plt.ylim(0., 1.) plt.savefig(os.path.join(outdir, 'profile.pdf')) return time_data_pd, outdir
def numerical_test(user_parameters): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 bifurcation_loads = [] # Create mesh and define function space # Define Dirichlet boundaries comm = MPI.comm_world default_parameters = getDefaultParameters() default_parameters.update(user_parameters) # FIXME: Not nice parameters = default_parameters parameters['code']['script'] = __file__ # import pdb; pdb.set_trace() signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir = '../output/traction/{}-{}CPU'.format(signature, size) Path(outdir).mkdir(parents=True, exist_ok=True) log(LogLevel.INFO, 'INFO: Outdir is: ' + outdir) BASE_DIR = os.path.dirname(os.path.realpath(__file__)) print(parameters['geometry']) d = { 'Lx': parameters['geometry']['Lx'], 'Ly': parameters['geometry']['Ly'], 'h': parameters['material']['ell'] / parameters['geometry']['n'] } geom_signature = hashlib.md5(str(d).encode('utf-8')).hexdigest() # -------------------------------------------------------- # Mesh creation with gmsh Lx = parameters['geometry']['Lx'] Ly = parameters['geometry']['Ly'] n = parameters['geometry']['n'] ell = parameters['material']['ell'] fname = os.path.join('../meshes', 'strip-{}'.format(geom_signature)) resolution = max(parameters['geometry']['n'] * Lx / ell, 5 / (Ly * 10)) resolution = 3 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))) mesh = mshr.generate_mesh(geom, resolution) log( LogLevel.INFO, 'Number of dofs: {}'.format( mesh.num_vertices() * (1 + parameters['general']['dim']))) if size == 1: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) Lx = parameters['geometry']['Lx'] ell = parameters['material']['ell'] savelag = 1 # mf = dolfin.MeshFunction("size_t", mesh, 1, 0) # Function Spaces V_u = dolfin.VectorFunctionSpace(mesh, "CG", 1) V_alpha = dolfin.FunctionSpace(mesh, "CG", 1) L2 = dolfin.FunctionSpace(mesh, "DG", 0) u = dolfin.Function(V_u, name="Total displacement") u.rename('u', 'u') alpha = Function(V_alpha) alpha_old = dolfin.Function(alpha.function_space()) alpha.rename('alpha', 'alpha') dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': alpha} Z = dolfin.FunctionSpace( mesh, dolfin.MixedElement([u.ufl_element(), alpha.ufl_element()])) z = dolfin.Function(Z) v, beta = dolfin.split(z) 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) 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 = [] bcs = {"damage": bcs_alpha, "elastic": bcs_u} ds = dolfin.Measure("ds", subdomain_data=mf) dx = dolfin.Measure("dx", metadata=parameters['compiler'], domain=mesh) ell = parameters['material']['ell'] # ----------------------- # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha)**2. + k_res w_1 = parameters['material']['sigma_D0']**2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) eps0t = Expression([['t', 0.], [0., 't']], t=0., degree=0) lmbda0 = parameters['material']['E'] * parameters['material']['nu'] / ( 1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E'] / 2. / (1.0 + parameters['material']['nu']) nu = parameters['material']['nu'] sigma0 = lmbda0 * tr(eps) * dolfin.Identity( parameters['general']['dim']) + 2 * mu0 * eps e1 = Constant((1., 0)) _sigma = ((1 - alpha)**2. + k_res) * sigma0 _snn = dolfin.dot(dolfin.dot(_sigma, e1), e1) # ------------------- ell = parameters['material']['ell'] E = parameters['material']['E'] def elastic_energy(u, alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res): a = (1 - alpha)**2. + k_res eps = sym(grad(u)) Wt = a*E*nu/(2*(1-nu**2.)) * tr(eps)**2. \ + a*E/(2.*(1+nu))*(inner(eps, eps)) return Wt * dx def dissipated_energy(alpha, w_1=w_1, ell=ell): return w_1 * (alpha + ell**2. * inner(grad(alpha), grad(alpha))) * dx def total_energy(u, alpha, k_res=k_res, w_1=w_1, E=E, nu=nu, ell=ell, eps0t=eps0t): elastic_energy_ = elastic_energy(u, alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res) dissipated_energy_ = dissipated_energy(alpha, w_1=w_1, ell=ell) return elastic_energy_ + dissipated_energy_ energy = total_energy(u, alpha) # Hessian = derivative(derivative(Wppt*dx, z, TestFunction(Z)), z, TrialFunction(Z)) def create_output(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_postproc = dolfin.XDMFFile( os.path.join(outdir, "postprocess.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True file_ealpha = dolfin.XDMFFile(os.path.join(outdir, "elapha.xdmf")) file_ealpha.parameters["functions_share_mesh"] = True file_ealpha.parameters["flush_output"] = True files = { 'output': file_out, 'postproc': file_postproc, 'eigen': file_eig, 'bifurcation': file_bif, 'ealpha': file_ealpha } return files files = create_output(outdir) solver = EquilibriumAM(energy, state, bcs, parameters=parameters) stability = StabilitySolver(energy, state, bcs, parameters=parameters) linesearch = LineSearch(energy, state) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] to_remove = [] perturb = False from matplotlib import cm log(LogLevel.INFO, '{}'.format(parameters)) for step, load in enumerate(load_steps): plt.clf() mineigs = [] exhaust_modes = [] log(LogLevel.CRITICAL, '====================== STEPPING ==========================') log(LogLevel.CRITICAL, 'CRITICAL: Solving load t = {:.2f}'.format(load)) alpha_old.assign(alpha) ut.t = load # (time_data_i, am_iter) = solver.solve(outdir) (time_data_i, am_iter) = solver.solve() # Second order stability conditions (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.CRITICAL, 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 # log(LogLevel.INFO, 'INFO: lmbda min {}'.format(lmbda_min_prev)) log(LogLevel.INFO, 'INFO: mineig {:.5e}'.format(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 log( LogLevel.INFO, 'INFO: About to bifurcate load {:.3f} step {}'.format( load, step)) bifurcation_loads.append(load) modes = np.where(stability.eigs < 0)[0] bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. # we postpone the update after the stability check if stable: solver.update() log( LogLevel.INFO, ' Current state is{}stable'.format( ' ' if stable else ' un')) else: # Continuation iteration = 1 mineigs.append(stability.mineig) while stable == False: log(LogLevel.INFO, 'Continuation iteration {}'.format(iteration)) plt.close('all') pert = [(_v, _b) for _v, _b in zip( stability.perturbations_v, stability.perturbations_beta)] _nmodes = len(pert) en_vars = [] h_opts = [] hbounds = [] en_perts = [] for i, mode in enumerate(pert): h_opt, bounds, enpert, en_var = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, mode[0], mode[1]) h_opts.append(h_opt) en_vars.append(en_var) hbounds.append(bounds) en_perts.append(enpert) if rank == 0: # fig = plt.figure(dpi=80, facecolor='w', edgecolor='k') # plt.subplot(1, 4, 1) # plt.set_cmap('binary') # # dolfin.plot(mesh, alpha = 1.) # dolfin.plot( # project(stability.inactivemarker1, L2), alpha = 1., vmin=0., vmax=1.) # plt.title('derivative zero') # plt.subplot(1, 4, 2) # # dolfin.plot(mesh, alpha = .5) # dolfin.plot( # project(stability.inactivemarker2, L2), alpha = 1., vmin=0., vmax=1.) # plt.title('ub tolerance') # plt.subplot(1, 4, 3) # # dolfin.plot(mesh, alpha = .5) # dolfin.plot( # project(stability.inactivemarker3, L2), alpha = 1., vmin=0., vmax=1.) # plt.title('alpha-alpha_old') # plt.subplot(1, 4, 4) # # dolfin.plot(mesh, alpha = .5) # dolfin.plot( # project(stability.inactivemarker4, L2), alpha = 1., vmin=0., vmax=1.) # plt.title('intersec deriv, ub') # plt.savefig(os.path.join(outdir, "inactivesets-{:.3f}-{:d}.pdf".format(load, iteration))) # plt.set_cmap('hot') fig = plt.figure(dpi=80, facecolor='w', edgecolor='k') for i, mode in enumerate(pert): plt.subplot(2, _nmodes + 1, i + 2) plt.axis('off') plot(mode[1], cmap=cm.ocean) plt.title( 'mode {} $h^*$={:.3f}\n $\\lambda_{}$={:.3e} \n $\\Delta E$={:.3e}' .format(i, h_opts[i], i, stability.eigs[i], en_vars[i]), fontsize=15) # plt.title('mode {}' # .format(i), fontsize= 15) plt.subplot(2, _nmodes + 1, _nmodes + 2 + 1 + i) plt.axis('off') _pert_beta = mode[1] _pert_v = mode[0] if hbounds[i][0] == hbounds[i][1] == 0: plt.plot(hbounds[i][0], 0) else: hs = np.linspace(hbounds[i][0], hbounds[i][1], 100) z = np.polyfit( np.linspace(hbounds[i][0], hbounds[i][1], len(en_perts[i])), en_perts[i], parameters['stability']['order']) p = np.poly1d(z) plt.plot(hs, p(hs), c='k') plt.plot(np.linspace(hbounds[i][0], hbounds[i][1], len(en_perts[i])), en_perts[i], marker='o', markersize=10, c='k') # import pdb; pdb.set_trace() plt.plot(hs, stability.eigs[i] * hs**2, c='r', lw=.3) plt.axvline(h_opts[i], lw=.3, c='k') plt.axvline(0, lw=2, c='k') # plt.title('{}'.format(i)) plt.tight_layout(h_pad=1.5, pad=1.5) # plt.legend() plt.savefig( os.path.join( outdir, "modes-{:.3f}-{}.pdf".format(load, iteration))) plt.close(fig) plt.clf() log(LogLevel.INFO, 'plotted modes') cont_data_pre = compile_continuation_data(state, energy) log(LogLevel.INFO, 'Estimated energy variation {:.3e}'.format(en_var)) Ealpha = Function(V_alpha) Ealpha.vector()[:] = assemble(stability.inactiveEalpha)[:] Ealpha.rename('Ealpha-{}'.format(iteration), 'Ealpha-{}'.format(iteration)) with files['ealpha'] as file: file.write(Ealpha, load) save_current_bifurcation = True # pick the first of the non exhausted modes- non_zero_h = np.where(abs(np.array(h_opts)) > DOLFIN_EPS)[0] log(LogLevel.INFO, 'Nonzero h {}'.format(non_zero_h)) avail_modes = set(non_zero_h) - set(exhaust_modes) opt_mode = 0 # opt_mode = np.argmin(en_vars) log(LogLevel.INFO, 'Energy vars {}'.format(en_vars)) log( LogLevel.INFO, 'Pick bifurcation mode {} out of {}'.format( opt_mode, len(en_vars))) # h_opt = min(h_opts[opt_mode],1.e-2) h_opt = h_opts[opt_mode] perturbation_v = stability.perturbations_v[opt_mode] perturbation_beta = stability.perturbations_beta[opt_mode] minmode = stability.minmode (perturbation_v, perturbation_beta) = minmode.split(deepcopy=True) # (perturbation_v, perturbation_beta) = stability.perturbation_v, stability.perturbation_beta def energy_1d(h): #return assemble(energy_functional(u + h * perturbation_v, alpha + h * perturbation_beta)) u_ = Function(u.function_space()) alpha_ = Function(alpha.function_space()) u_.vector( )[:] = u.vector()[:] + h * perturbation_v.vector()[:] alpha_.vector()[:] = alpha.vector( )[:] + h * perturbation_beta.vector()[:] u_.vector().vec().ghostUpdate() alpha_.vector().vec().ghostUpdate() return assemble(total_energy(u_, alpha_)) (hmin, hmax) = linesearch.admissible_interval( alpha, alpha_old, perturbation_beta) hs = np.linspace(hmin, hmax, 20) energy_vals = np.array([energy_1d(h) for h in hs]) stability.solve(solver.damage.problem.lb) Hzz = assemble(stability.H * minmode * minmode) Gz = assemble(stability.J * minmode) mineig_z = Hzz / assemble(dot(minmode, minmode) * dx) energy_vals_quad = energy_1d(0) + hs * Gz + hs**2 * Hzz / 2 # h_opt = hs[np.argmin(energy_vals)] print('computed h_opt {}'.format(hs[np.argmin(energy_vals)])) print("%%%%%%%%% ", mineig_z, "-", mineig) if rank == 0: plt.figure() # plt.plot(hs,energy_vals, marker = 'o') plt.plot(hs, energy_vals, marker='o', label="exact") plt.plot(hs, energy_vals_quad, label="quadratic approximation") plt.legend() plt.title("eig {:.4f} vs {:.4f} expected".format( mineig_z, mineig)) plt.axvline(h_opt) # import pdb; pdb.set_trace() plt.savefig( os.path.join(outdir, "energy1d-{:.3f}.pdf".format(load))) iteration += 1 log(LogLevel.CRITICAL, 'Bifurcating') save_current_bifurcation = True alpha_bif.assign(alpha) alpha_bif_old.assign(alpha_old) # admissible perturbation 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() log(LogLevel.INFO, 'min a+h_opt beta_{} = {}'.format(opt_mode, min(aval))) log(LogLevel.INFO, 'max a+h_opt beta_{} = {}'.format(opt_mode, max(aval))) log(LogLevel.INFO, 'Solving equilibrium from perturbed state') (time_data_i, am_iter) = solver.solve(outdir) # (time_data_i, am_iter) = solver.solve() log(LogLevel.INFO, 'Checking stability of new state') (stable, negev) = stability.solve(solver.damage.problem.lb) mineigs.append(stability.mineig) log( LogLevel.INFO, 'Continuation iteration {}, current state is{}stable'. format(iteration, ' ' if stable else ' un')) cont_data_post = compile_continuation_data(state, energy) DeltaE = (cont_data_post['energy'] - cont_data_pre['energy']) relDeltaE = (cont_data_post['energy'] - cont_data_pre['energy']) / cont_data_pre['energy'] release = DeltaE < 0 and np.abs( DeltaE) > parameters['stability']['cont_rtol'] log( LogLevel.INFO, 'Continuation: post energy {} - pre energy {}'.format( cont_data_post['energy'], cont_data_pre['energy'])) log( LogLevel.INFO, 'Actual absolute energy variation Delta E = {:.7e}'.format( DeltaE)) log( LogLevel.INFO, 'Actual relative energy variation relDelta E = {:.7e}'. format(relDeltaE)) log(LogLevel.INFO, 'Iter {} mineigs = {}'.format(iteration, mineigs)) if rank == 0: plt.figure() plt.plot(mineigs, marker='o') plt.axhline(0.) plt.savefig( os.path.join(outdir, "mineigs-{:.3f}.pdf".format(load))) # continuation criterion if abs(np.diff(mineigs)[-1]) > 1e-10: log(LogLevel.INFO, 'Min eig change = {:.3e}'.format(np.diff(mineigs)[-1])) log(LogLevel.INFO, 'Continuing perturbations') else: log(LogLevel.INFO, 'Min eig change = {:.3e}'.format(np.diff(mineigs)[-1])) log(LogLevel.CRITICAL, 'We are stuck in the matrix') log(LogLevel.WARNING, 'Exploring next mode') exhaust_modes.append(opt_mode) # import pdb; pdb.set_trace() log(LogLevel.WARNING, 'Continuing load program') break # # if not release: # log(LogLevel.CRITICAL, 'Small nergy release , we are stuck in the matrix') # log(LogLevel.CRITICAL, 'No decrease in energy, we are stuck in the matrix') # log(LogLevel.WARNING, 'Continuing load program') # import pdb; pdb.set_trace() # break # else: # # warn # log(LogLevel.CRITICAL, 'Found zero increment, we are stuck in the matrix') # log(LogLevel.WARNING, 'Exploring next mode') # exhaust_modes.append(opt_mode) # import pdb; pdb.set_trace() # # log(LogLevel.WARNING, 'Continuing load program') # # break solver.update() log(LogLevel.INFO, 'bifurcation loads : {}'.format(bifurcation_loads)) np.save(os.path.join(outdir, 'bifurcation_loads'), bifurcation_loads, allow_pickle=True, fix_imports=True) if save_current_bifurcation: time_data_i['h_opt'] = h_opt time_data_i['max_h'] = hbounds[opt_mode][1] time_data_i['min_h'] = hbounds[opt_mode][0] modes = np.where(stability.eigs < 0)[0] leneigs = len(modes) maxmodes = min(3, leneigs) with files['bifurcation'] as file: for n in range(len(pert)): mode = dolfin.project(stability.perturbations_beta[n], V_alpha) modename = 'beta-%d' % n mode.rename(modename, modename) log(LogLevel.INFO, 'Saved mode {}'.format(modename)) file.write(mode, load) # with files['file_bif_postproc'] as file: # leneigs = len(modes) # maxmodes = min(3, leneigs) # beta0v = dolfin.project(stability.perturbation_beta, V_alpha) # log(LogLevel.DEBUG, 'DEBUG: irrev {}'.format(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'), en_perts, allow_pickle=True, fix_imports=True) with files['eigen'] 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') file.write(_v, load) file.write(_beta, load) # save_current_bifurcation = False time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble( elastic_energy(u, alpha, E=E, nu=nu, eps0t=eps0t, k_res=k_res)) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * parameters['material']['ell']**2. * inner(grad(alpha), grad(alpha))) * dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf time_data_i["sigma"] = 1 / Ly * dolfin.assemble(_snn * ds(1)) # import pdb; pdb.set_trace() log( LogLevel.INFO, "Load/time step {:.4g}: converged in iterations: {:3d}, err_alpha={:.4e}" .format(time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) with files['output'] as file: file.write(alpha, load) file.write(u, load) with files['postproc'] as file: file.write_checkpoint(alpha, "alpha-{}".format(step), step, append=True) file.write_checkpoint(u, "u-{}".format(step), step, append=True) log(LogLevel.INFO, 'INFO: written postprocessing step {}'.format(step)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) if rank == 0: # plt.clf() # if load>1.1: # import pdb; pdb.set_trace() # plt.plot(time_data_i["alpha_error"], marker='o') # plt.title('error, criterion: {}'.format(parameters['equilibrium']['criterion'])) # plt.axhline(parameters['equilibrium']['tol']) # plt.savefig(os.path.join(outdir, 'errors-{}.pdf'.format(step))) # plt.clf() # plt.colorbar(plot(alpha)) # fig = plt.figure() # plot(alpha) # plt.savefig(os.path.join(outdir, 'alpha.pdf')) # log(LogLevel.INFO, "Saved figure: {}".format(os.path.join(outdir, 'alpha.pdf'))) plt.close('all') fig = plt.figure() for i, d in enumerate(time_data_pd['eigs']): # if d is not (np.inf or np.nan or float('inf')): if np.isfinite(d).all(): lend = len(d) if isinstance(d, np.ndarray) else 1 plt.scatter([(time_data_pd['load'].values)[i]] * lend, d, c=np.where(np.array(d) < 0., 'red', 'black')) plt.axhline(0, c='k', lw=2.) plt.xlabel('t') # [plt.axvline(b) for b in bifurcation_loads] # import pdb; pdb.set_trace() log(LogLevel.INFO, 'Spectrum bifurcation loads : {}'.format(bifurcation_loads)) plt.xticks(list(plt.xticks()[0]) + bifurcation_loads) [plt.axvline(bif, lw=2, c='k') for bif in bifurcation_loads] plt.savefig(os.path.join(outdir, "spectrum.pdf"), bbox_inches='tight') # plt.plot() return time_data_pd, outdir
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 numerical_test( user_parameters, ell=0.05, nu=0., ): time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 bifurcation_loads = [] # Create mesh and define function space # geometry_parameters = {'R': 1., 'n': 5} # Define Dirichlet boundaries comm = MPI.comm_world with open('../parameters/form_compiler.yml') as f: form_compiler_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: solver_parameters = yaml.load(f, Loader=yaml.FullLoader) with open('../parameters/solvers_default.yml') as f: damage_parameters = yaml.load(f, Loader=yaml.FullLoader)['damage'] with open('../parameters/solvers_default.yml') as f: elasticity_parameters = yaml.load(f, Loader=yaml.FullLoader)['elasticity'] with open('../parameters/film.yaml') as f: material_parameters = yaml.load(f, Loader=yaml.FullLoader)['material'] with open('../parameters/loading.yaml') as f: loading_parameters = yaml.load(f, Loader=yaml.FullLoader)['loading'] with open('../parameters/stability.yaml') as f: stability_parameters = yaml.load(f, Loader=yaml.FullLoader)['stability'] with open('../parameters/stability.yaml') as f: inertia_parameters = yaml.load(f, Loader=yaml.FullLoader)['inertia'] with open('../parameters/stability.yaml') as f: eigen_parameters = yaml.load(f, Loader=yaml.FullLoader)['eigen'] # import pdb; pdb.set_trace() default_parameters = { 'code': { **code_parameters }, 'compiler': { **form_compiler_parameters }, 'eigen': { **eigen_parameters }, # 'geometry': {**geometry_parameters}, 'inertia': { **inertia_parameters }, 'loading': { **loading_parameters }, 'material': { **material_parameters }, 'solver': { **solver_parameters }, 'stability': { **stability_parameters }, 'elasticity': { **elasticity_parameters }, 'damage': { **damage_parameters }, } default_parameters.update(user_parameters) # FIXME: Not nice parameters = default_parameters signature = hashlib.md5(str(parameters).encode('utf-8')).hexdigest() outdir = '../test/output/film2d/{}'.format(signature) # outdir = '../test/output/test_film2d-init-{}'.format(signature) Path(outdir).mkdir(parents=True, exist_ok=True) log(LogLevel.INFO, 'INFO: Outdir is: ' + outdir) R = parameters['geometry']['R'] # Mesh1 ================================== # geom = mshr.Circle(dolfin.Point(0., 0.), R) # resolution = max(geometry_parameters['n'] * Lx / ell, 1/(Ly*10)) # resolution = max(parameters['geometry']['n'] * R / ell, (10/R)) # resolution = 10 # log(LogLevel.INFO, 'mesh resolution {}'.format(resolution)) # mesh = mshr.generate_mesh(geom, resolution) # Mesh2 ================================== # mesh = dolfin.Mesh("../scripts/meshes/diskR3-mesh.xml") # Mesh3 ================================== # fname = os.path.join('../meshes', 'circle-init-{}'.format(geom_signature)) d = { 'rad': parameters['geometry']['R'], 'h': parameters['material']['ell'] / parameters['geometry']['n'] } geom_signature = hashlib.md5(str(d).encode('utf-8')).hexdigest() fname = os.path.join('../meshes', 'circle-{}'.format(geom_signature)) if os.path.isfile(fname + '.xml'): log(LogLevel.INFO, "Meshfile {} exists".format(fname)) mesh = dolfin.Mesh("{}.xml".format(fname)) else: log(LogLevel.INFO, "Creating meshfile: %s" % fname) log(LogLevel.INFO, "DEBUG: parameters: %s" % d) # mesh_template = open('../scripts/templates/circle_template_init.geo') if MPI.rank(MPI.comm_world) == 0: mesh_template = open('../scripts/templates/circle_template.geo') src = Template(mesh_template.read()) geofile = src.substitute(d) with open(fname + ".geo", 'w') as f: f.write(geofile) cmd1 = 'gmsh {}.geo -2 -o {}.msh'.format(fname, fname) cmd2 = 'dolfin-convert -i gmsh {}.msh {}.xml'.format(fname, fname) log( LogLevel.INFO, 'Unable to handle mesh generation at the moment, please generate the mesh and test again.' ) log(LogLevel.INFO, cmd1) log(LogLevel.INFO, cmd2) sys.exit() log(LogLevel.INFO, 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('{}.xml'.format(fname)) mesh_xdmf = XDMFFile("{}.xdmf".format(fname)) mesh_xdmf.write(mesh) log(LogLevel.INFO, fname) # boundary_meshfunction = dolfin.MeshFunction("size_t", mesh, "{}_facet_region.xml".format(fname)) # cells_meshfunction = dolfin.MeshFunction("size_t", mesh, "{}_physical_region.xml".format(fname)) # 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 log(LogLevel.WARNING, 'porcoilclero') if size == 1: meshf = dolfin.File(os.path.join(outdir, "mesh.xml")) meshf << mesh plot(mesh) plt.savefig(os.path.join(outdir, "mesh.pdf"), bbox_inches='tight') log(LogLevel.INFO, 'num vertices {}'.format(mesh.num_vertices())) log( LogLevel.INFO, 'Number of dofs: {}'.format( mesh.num_vertices() * (1 + parameters['general']['dim']))) # import pdb; pdb.set_trace() with open(os.path.join(outdir, 'parameters.yaml'), "w") as f: yaml.dump(parameters, f, default_flow_style=False) R = parameters['geometry']['R'] ell = parameters['material']['ell'] savelag = 1 # left = dolfin.CompiledSubDomain("near(x[0], -Lx/2.)", Lx=Lx) # right = dolfin.CompiledSubDomain("near(x[0], Lx/2.)", Lx=Lx) # 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) 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") u.rename('u', 'u') alpha = Function(V_alpha) alpha_old = dolfin.Function(alpha.function_space()) alpha.rename('alpha', 'alpha') dalpha = TrialFunction(V_alpha) alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) state = {'u': u, 'alpha': 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, dolfin.Constant((0,0)), left), # dolfin.DirichletBC(V_u, dolfin.Constant((0,0)), right), # dolfin.DirichletBC(V_u, (0, 0), left_bottom_pt, method="pointwise") # ] bcs_u = [dolfin.DirichletBC(V_u, dolfin.Constant((0., 0.)), 'on_boundary')] # bcs_u = [] # bcs_alpha_l = DirichletBC(V_alpha, Constant(0.0), left) # bcs_alpha_r = DirichletBC(V_alpha, Constant(0.0), right) # bcs_alpha =[bcs_alpha_l, bcs_alpha_r] # bcs_alpha = [DirichletBC(V_alpha, Constant(0.0), 'on_boundary')] bcs_alpha = [] # bcs_alpha = [DirichletBC(V_alpha, Constant(1.), boundary_meshfunction, 101)] bcs = {"damage": bcs_alpha, "elastic": bcs_u} ell = parameters['material']['ell'] # Problem definition # Problem definition k_res = parameters['material']['k_res'] a = (1 - alpha)**2. + k_res w_1 = parameters['material']['sigma_D0']**2 / parameters['material']['E'] w = w_1 * alpha eps = sym(grad(u)) eps0t = Expression([['t', 0.], [0., 't']], t=0., degree=0) X0 = parameters['geometry']['R'] lmbda0 = parameters['material']['E'] * parameters['material']['nu'] / ( 1. - parameters['material']['nu'])**2. mu0 = parameters['material']['E'] / 2. / (1.0 + parameters['material']['nu']) nu = parameters['material']['nu'] # Wt = a*parameters['material']['E']*nu/(2*(1-nu**2.)) * tr(eps-eps0t)**2. \ # + a*parameters['material']['E']*(inner(eps-eps0t, eps-eps0t)/(2.*(1+nu))) \ # + 1./2.*1./parameters['material']['ell_e']**2.*dot(u, u) # effective coeff of trace = lmbda mu / (lmbda + 2 mu) = nu/(1-nu) # Wt = a* lmbda0/(lmbda0+ 2.*mu0) * tr(eps-eps0t)**2. \ # + a*2.*mu0*(inner(eps-eps0t, eps-eps0t)) \ Wt = a*parameters['material']['E']*nu/((1+nu)*(1-2*nu)) * tr(eps-eps0t)**2. \ + a*parameters['material']['E']*(inner(eps-eps0t, eps-eps0t)/(2.*(1+nu))) \ + 1./2.*X0**2./parameters['material']['ell_e']**2.*dot(u, u) energy = Wt * dx + w_1 * (alpha + (parameters['material']['ell'] / X0**2.) * inner(grad(alpha), grad(alpha))) * dx file_out = dolfin.XDMFFile(os.path.join(outdir, "output.xdmf")) file_out.parameters["functions_share_mesh"] = True file_out.parameters["flush_output"] = True file_postproc = dolfin.XDMFFile(os.path.join(outdir, "postprocess.xdmf")) file_postproc.parameters["functions_share_mesh"] = True file_postproc.parameters["flush_output"] = True file_eig = dolfin.XDMFFile(os.path.join(outdir, "perturbations.xdmf")) file_eig.parameters["functions_share_mesh"] = True file_eig.parameters["flush_output"] = True file_bif = dolfin.XDMFFile(os.path.join(outdir, "bifurcation.xdmf")) file_bif.parameters["functions_share_mesh"] = True file_bif.parameters["flush_output"] = True file_bif_postproc = dolfin.XDMFFile( os.path.join(outdir, "bifurcation_postproc.xdmf")) file_bif_postproc.parameters["functions_share_mesh"] = True file_bif_postproc.parameters["flush_output"] = True solver = EquilibriumSolver(energy, state, bcs, parameters=parameters) stability = StabilitySolver(energy, state, bcs, parameters=parameters) # stability = StabilitySolver(energy, state, bcs, parameters = parameters['stability'], rayleigh= [rP, rN]) linesearch = LineSearch(energy, state) load_steps = np.linspace(parameters['loading']['load_min'], parameters['loading']['load_max'], parameters['loading']['n_steps']) time_data = [] time_data_pd = [] spacetime = [] lmbda_min_prev = 1e-6 bifurcated = False bifurcation_loads = [] save_current_bifurcation = False bifurc_i = 0 alpha_bif = dolfin.Function(V_alpha) alpha_bif_old = dolfin.Function(V_alpha) bifurcation_loads = [] perturb = False _file = dolfin.XDMFFile(os.path.join(outdir, "test.xdmf")) log(LogLevel.INFO, '{}'.format(parameters)) log( LogLevel.INFO, 'ell/X0 = {}, ell/ell_e = {}, ell_e/X0 = {}'.format( parameters['material']['ell'] / X0, parameters['material']['ell'] / parameters['material']['ell_e'], parameters['material']['ell_e'] / parameters['geometry']['R'])) break_after_bifurcation = False file_debug = dolfin.XDMFFile('/Users/kumiori/debugalpha.xdmf') file_debug.parameters["functions_share_mesh"] = True file_debug.parameters["flush_output"] = True from matplotlib import cm for step, load in enumerate(load_steps): log(LogLevel.INFO, '==========================================================') log(LogLevel.INFO, '====================== STEPPING ==========================') log(LogLevel.INFO, 'INFO: Solving load t = {:.2f}'.format(load)) alpha_old.assign(alpha) eps0t.t = load (time_data_i, am_iter) = solver.solve(debugpath=outdir) # Second order stability conditions (stable, negev) = stability.solve(solver.damage.problem.lb) log(LogLevel.INFO, 'Current state is{}stable'.format(' ' if stable else ' un')) mineig = stability.mineig if hasattr(stability, 'mineig') else 0.0 log(LogLevel.INFO, 'INFO: lmbda min {}'.format(lmbda_min_prev)) log(LogLevel.INFO, 'INFO: mineig {}'.format(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 log(LogLevel.INFO, 'INFO: About to bifurcate load {} step {}'.format(load, step)) bifurcation_loads.append(load) modes = np.where(stability.eigs < 0)[0] bifurc_i += 1 lmbda_min_prev = mineig if hasattr(stability, 'mineig') else 0. # we postpone the update after the stability check if stable: solver.update() log( LogLevel.INFO, ' Current state is{}stable'.format( ' ' if stable else ' un')) else: # Continuation # save_current_bifurcation = True # save_stability = stability iteration = 1 while stable == False: log(LogLevel.CRITICAL, 'Continuation iteration {}'.format(iteration)) # # linesearch cont_data_pre = compile_continuation_data(state, energy) perturbation_v = stability.perturbation_v perturbation_beta = stability.perturbation_beta perturbation_v = stability.perturbations_v[0] perturbation_beta = stability.perturbations_beta[0] log(LogLevel.INFO, ' Perturbations') # log(LogLevel.INFO, '{}'.format(stability. perturbations_beta)) pert = [(_v, _b) for _v, _b in zip( stability.perturbations_v, stability.perturbations_beta)] for n in range(len(pert)): linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, pert[n][0], pert[n][1]) if size == 1: fig = plt.figure( figsize=(4, 1.5), dpi=180, ) _nmodes = len(pert) for mode in range(_nmodes): plt.subplot(2, int(_nmodes / 2) + _nmodes % 2, mode + 1) ax = plt.gca() plt.axis('off') plot(stability.perturbations_beta[mode], vmin=-1., vmax=1.) # ax.set_title('mode: '.format(mode)) fig.savefig(os.path.join(outdir, "modes-{:.3f}.pdf".format(load)), bbox_inches="tight") plt.close() fig = plt.figure(figsize=((_nmodes + 1) * 3, 3), dpi=80, facecolor='w', edgecolor='k') fig.suptitle('Load {:3f}'.format(load), fontsize=16) plt.subplot(2, _nmodes + 1, 1) plt.title('$\\alpha$ (max = {:2.2f})'.format( max(alpha.vector()[:]))) plt.set_cmap('coolwarm') plt.axis('off') plot(alpha, vmin=0., vmax=1.) plt.set_cmap('hot') for i, mode in enumerate(pert): plt.subplot(2, _nmodes + 1, i + 2) plt.axis('off') plot(mode[1], cmap=cm.ocean, rowspan=2) h_opt, bounds, energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, mode[0], mode[1]) # import pdb; pdb.set_trace() # plt.title('mode {}\n$\\lambda_{{{}}}={:.1e},$\n$h_opt$={:.3f}'.format( # i, i, stability.eigs[i], h_opt)) # print('plot mode {}'.format(i)) # plt.tight_layout(h_pad=0.0, pad=1.5) # plt.savefig(os.path.join(outdir, "modes-{:3.4f}.png".format(load))) for i, mode in enumerate(pert): plt.subplot(2, _nmodes + 1, _nmodes + 2 + 1 + i) plt.axis('off') _pert_beta = mode[1] _pert_v = mode[0] h_opt, bounds, energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, mode[0], mode[1]) # bounds = mode['interval'] # import pdb; pdb.set_trace() if bounds[0] == bounds[1] == 0: plt.plot(bounds[0], 0) else: hs = np.linspace(bounds[0], bounds[1], 100) z = np.polyfit( np.linspace(bounds[0], bounds[1], len(energy_perturbations)), energy_perturbations, parameters['stability']['order']) p = np.poly1d(z) plt.plot(hs, p(hs), c='k') plt.plot(np.linspace(bounds[0], bounds[1], len(energy_perturbations)), energy_perturbations, marker='o', c='k') # plt.axvline(mode['hstar']) plt.axvline(0, lw=.5, c='k') # plt.title('{}'.format(i)) plt.tight_layout(h_pad=1.5, pad=1.5) # plt.legend() plt.savefig( os.path.join(outdir, "modes-{:3.4f}.pdf".format(load))) plt.close(fig) plt.clf() log(LogLevel.INFO, 'INFO: plotted modes') h_opt, (hmin, hmax), energy_perturbations = linesearch.search( { 'u': u, 'alpha': alpha, 'alpha_old': alpha_old }, perturbation_v, perturbation_beta) log( LogLevel.INFO, 'h_opt {}, (hmin, hmax) {}, energy_perturbations {}'. format(h_opt, (hmin, hmax), energy_perturbations)) # # stable = True if h_opt != 0: log(LogLevel.INFO, ' Bifurcating') 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() file_debug.write_checkpoint(alpha, 'alpha_new', 0, append=True) alpha.rename('alpha_new', 'alpha_new') file_debug.write(alpha) __v = alpha - alpha_old _v = dolfin.project(__v, V_alpha) file_debug.write(_v) alpha.rename('alpha', 'alpha') plt.clf() plt.colorbar(dolfin.plot(__v, cmap=cm.binary)) plt.savefig( '/Users/kumiori/apert-aold-{}-new-{}.pdf'.format( step, iteration)) # import pdb; pdb.set_trace() (time_data_i, am_iter) = solver.solve(debugpath=outdir) file_debug.write_checkpoint(alpha, 'alpha_new_post', 0, append=True) alpha.rename('alpha_new_post', 'alpha_new_post') file_debug.write(alpha) alpha.rename('alpha', 'alpha') (stable, negev) = stability.solve(solver.damage.problem.lb) log( LogLevel.INFO, ' Continuation iteration {}, current state is{}stable' .format(iteration, ' ' if stable else ' un')) iteration += 1 cont_data_post = compile_continuation_data(state, energy) criterion = (cont_data_post['energy'] - cont_data_pre['energy'] ) / cont_data_pre['energy'] < parameters[ 'stability']['cont_rtol'] log(LogLevel.INFO, 'INFO: Continuation criterion {}'.format(criterion)) else: # warn log(LogLevel.WARNING, 'Found zero increment, we are stuck in the matrix') log(LogLevel.WARNING, 'Continuing load program') import pdb pdb.set_trace() break # solver.update() # if save_current_bifurcation: # import pdb; pdb.set_trace() # time_data_i['h_opt'] = h_opt # time_data_i['max_h'] = hmax # time_data_i['min_h'] = hmin # modes = np.where(save_stability.eigs < 0)[0] # leneigs = len(modes) # maxmodes = min(3, leneigs) # with file_bif as file: # for n in range(maxmodes): # mode = dolfin.project(save_stability.linsearch[n]['beta_n'], V_alpha) # modename = 'beta-%d'%n # mode.rename(modename, modename) # log(LogLevel.INFO, 'Saved mode {}'.format(modename)) # file.write(mode, step) # with file_bif_postproc as file: # # leneigs = len(modes) # # maxmodes = min(3, leneigs) # beta0v = dolfin.project(save_stability.perturbation_beta, V_alpha) # log(LogLevel.DEBUG, 'DEBUG: irrev {}'.format(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-{}'.format(step)), energy_perturbations, allow_pickle=True, fix_imports=True) # if size == 1: # dolfin.plot(perturbation_beta) # plt.savefig(os.path.join(outdir, "pert_beta.pdf")) # 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') # file.write(_v, load) # file.write(_beta, load) # break_after_bifurcation = True time_data_i["load"] = load time_data_i["alpha_max"] = max(alpha.vector()[:]) time_data_i["elastic_energy"] = dolfin.assemble(a * Wt * dx) time_data_i["dissipated_energy"] = dolfin.assemble( (w + w_1 * material_parameters['ell']**2. * inner(grad(alpha), grad(alpha))) * dx) time_data_i["stable"] = stability.stable time_data_i["# neg ev"] = stability.negev time_data_i["eigs"] = stability.eigs if hasattr(stability, 'eigs') else np.inf log( LogLevel.INFO, "Load/time step {:.4g}: converged in iterations: {:3d}, err_alpha={:.4e}" .format(time_data_i["load"], time_data_i["iterations"][0], time_data_i["alpha_error"][0])) time_data.append(time_data_i) time_data_pd = pd.DataFrame(time_data) # import pdb; pdb.set_trace() # plt.figure() # plt1 = time_data_pd.plot( # x=time_data_pd["load"], # y=time_data_pd["iterations"], # marker=".", # logy=True, # logx=False, # ) # plt.savefig(os.path.join(outdir, "plot_err.pdf")) with file_out as file: file.write(alpha, load) file.write(u, load) with file_postproc as file: file.write_checkpoint(alpha, "alpha-{}".format(step), step, append=True) file.write_checkpoint(u, "u-{}".format(step), step, append=True) log(LogLevel.INFO, 'INFO: written postprocessing step {}'.format(step)) if break_after_bifurcation: log(LogLevel.CRITICAL, ' Bifurcarted. Breaking here') break # step = it # for s in range(step): # log(LogLevel.INFO, 'INFO: reading step {}'.format(s)) # f.read_checkpoint(alpha, "alpha-{}".format(s)) # log(LogLevel.INFO, 'INFO: read step {}'.format(step)) # f.close() # import pdb; pdb.set_trace() # spacetime.append(get_trace(alpha)) time_data_pd.to_json(os.path.join(outdir, "time_data.json")) if size == 1: def format_space(x, pos, xresol=100): return '$%1.1f$' % ((-x + xresol / 2) / xresol) def format_time(t, pos, xresol=100): return '$%1.1f$' % ((t - parameters['loading']['load_min']) / parameters['loading']['n_steps'] * parameters['loading']['load_max']) from matplotlib.ticker import FuncFormatter, MaxNLocator # ax = plt.gca() # ax.yaxis.set_major_formatter(FuncFormatter(format_space)) # ax.xaxis.set_major_formatter(FuncFormatter(format_time)) plot(alpha) plt.savefig(os.path.join(outdir, 'alpha.pdf')) log(LogLevel.INFO, "Saved figure: {}".format(os.path.join(outdir, 'alpha.pdf'))) return time_data_pd, outdir