params['material']['sigma_D0']) params['geometry']['Ly'] = 1 fig1, ax1 = pp.plot_energy(params, data, tc) # visuals.setspines2() mu = params['material']['E'] / 2. # elast_en = [1./2.*2.*mu*eps**2 for eps in data['load']] elast_en = [ 1. / 2. * params['material']['E'] * eps**2 for eps in data['load'] ] plt.plot(data['load'], elast_en, c='k') ax1.axvline(pp.t_stab(ell), c='k', ls='-', lw=2, label='$t^{cr}_s$') ax1.axvline(pp.t_bif(ell), c='k', ls='-.', lw=2, label=r'$t^{cr}_b$') plt.title('${}$'.format(lab)) (fig2, ax1, ax2) = pp.plot_spectrum(params, data, tc) ax1.axvline(pp.t_stab(ell), c='k', ls='-', lw=2, label='$t^{cr}_s$') ax1.axvline(pp.t_bif(ell), c='k', ls='-.', lw=2, label=r'$t^{cr}_b$') plt.plot(np.linspace(1, params['time_stepping']['load_max'], 30), [ 1 - (t / params['material']['sigma_D0'] / params['material']['E']) **(2 / (1 - 2)) for t in np.linspace(1, params['time_stepping']['load_max'], 30) ], c='k', lw=.5) plt.title('${}$'.format(lab)) # visuals.setspines2() ax1.set_ylim(-1., .2) # fig1.savefig("/Users/kumiori/Documents/WIP/paper_stability/fig/energy-traction-{}.pdf".format(signature), bbox_inches='tight')
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_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