def compute_unsteadiness(self): """ Set 'unsteadiness' metric to compare to `steady_tolerance` for choosing to stop at steady state. """ time_residual = fenics.Function(self.state.solution.leaf_node().function_space()) time_residual.assign(self.state.solution.leaf_node() - self.old_state.solution.leaf_node()) L2_norm_relative_time_residual = fenics.norm(time_residual.leaf_node(), "L2")/ \ fenics.norm(self.old_state.solution.leaf_node(), "L2") self.unsteadiness = L2_norm_relative_time_residual
def unsteadiness(sim): time_residual = \ fenics.Function(sim.function_space) time_residual.assign(sim._solutions[0].leaf_node() - sim._solutions[1].leaf_node()) L2_norm_relative_time_residual = fenics.norm( time_residual, "L2")/ \ fenics.norm(sim._solutions[1].leaf_node(), "L2") return L2_norm_relative_time_residual
def Newton_manual(F, udp, bcs, atol, rtol, max_it, lmbda, udp_res, VVQ): #Reset counters Iter = 0 residual = 1 rel_res = residual dw = TrialFunction(VVQ) Jac = derivative(F, udp, dw) # Jacobi while rel_res > rtol and residual > atol and Iter < max_it: A = assemble(Jac) A.ident_zeros() b = assemble(-F) [bc.apply(A, b, udp.vector()) for bc in bcs] #solve(A, udp_res.vector(), b, "superlu_dist") solve(A, udp_res.vector(), b) #, "mumps") udp.vector()[:] = udp.vector()[:] + lmbda * udp_res.vector()[:] #udp.vector().axpy(1., udp_res.vector()) [bc.apply(udp.vector()) for bc in bcs] rel_res = norm(udp_res, 'l2') residual = b.norm('l2') if MPI.rank(mpi_comm_world()) == 0: print "Newton iteration %d: r (atol) = %.3e (tol = %.3e), r (rel) = %.3e (tol = %.3e) " \ % (Iter, residual, atol, rel_res, rtol) Iter += 1 return udp
def test_run_inversion(persistent_temp_model, monkeypatch): work_dir = persistent_temp_model["work_dir"] toml_file = persistent_temp_model["toml_filename"] # Switch to the working directory monkeypatch.chdir(work_dir) # Get expected values from the toml file params = config.ConfigParser(toml_file, top_dir=work_dir) expected_cntrl_norm = params.testing.expected_cntrl_norm expected_J_inv = params.testing.expected_J_inv EQReset() # Run the thing mdl_out = run_inv.run_inv(toml_file) cntrl = mdl_out.solvers[0].get_control()[0] cntrl_norm = norm(cntrl.vector()) J_inv = mdl_out.solvers[0].J_inv.value() pytest.check_float_result(cntrl_norm, expected_cntrl_norm, work_dir, 'expected_cntrl_norm') pytest.check_float_result(J_inv, expected_J_inv, work_dir, 'expected_J_inv')
def test_run_forward(existing_temp_model, monkeypatch, setup_deps, request): setup_deps.set_case_dependency(request, ["test_run_inversion"]) work_dir = existing_temp_model["work_dir"] toml_file = existing_temp_model["toml_filename"] # Switch to the working directory monkeypatch.chdir(work_dir) # Get expected values from the toml file params = config.ConfigParser(toml_file, top_dir=work_dir) expected_delta_qoi = params.testing.expected_delta_qoi expected_u_norm = params.testing.expected_u_norm EQReset() mdl_out = run_forward.run_forward(toml_file) slvr = mdl_out.solvers[0] delta_qoi = slvr.Qval_ts[-1] - slvr.Qval_ts[0] u_norm = norm(slvr.U) pytest.check_float_result(delta_qoi, expected_delta_qoi, work_dir, 'expected_delta_qoi') pytest.check_float_result(u_norm, expected_u_norm, work_dir, 'expected_u_norm')
def test_run_eigendec(existing_temp_model, monkeypatch, setup_deps, request): setup_deps.set_case_dependency(request, ["test_run_inversion"]) work_dir = existing_temp_model["work_dir"] toml_file = existing_temp_model["toml_filename"] # Switch to the working directory monkeypatch.chdir(work_dir) # Get expected values from the toml file params = config.ConfigParser(toml_file, top_dir=work_dir) expected_evals_sum = params.testing.expected_evals_sum expected_evec0_norm = params.testing.expected_evec0_norm EQReset() mdl_out = run_eigendec.run_eigendec(toml_file) slvr = mdl_out.solvers[0] evals_sum = np.sum(slvr.eigenvals) evec0_norm = norm(slvr.eigenfuncs[0]) pytest.check_float_result(evals_sum, expected_evals_sum, work_dir, 'expected_evals_sum') pytest.check_float_result(evec0_norm, expected_evec0_norm, work_dir, 'expected_evec0_norm')
def Newton_manual(F, vd, bcs, J, atol, rtol, max_it, lmbda\ , vd_res): #Reset counters Iter = 0 residual = 1 rel_res = residual while rel_res > rtol and residual > atol and Iter < max_it: A = assemble(J, keep_diagonal = True) A.ident_zeros() b = assemble(-F) [bc.apply(A, b, vd.vector()) for bc in bcs] #solve(A, vd_res.vector(), b, "superlu_dist") #solve(A, vd_res.vector(), b, "mumps") solve(A, vd_res.vector(), b) vd.vector().axpy(1., vd_res.vector()) [bc.apply(vd.vector()) for bc in bcs] rel_res = norm(vd_res, 'l2') residual = b.norm('l2') if MPI.rank(mpi_comm_world()) == 0: print "Newton iteration %d: r (atol) = %.3e (tol = %.3e), r (rel) = %.3e (tol = %.3e) " \ % (Iter, residual, atol, rel_res, rtol) Iter += 1 #Reset residual = 1 rel_res = residual Iter = 0 return vd
def impl_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False): (u0, p0, v0) = fe.split(w0) bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_upv.sub(0), V_upv.sub(1), V_upv.sub(2), boundaries) # Lagrange function (without constraint) (u1, p1, v1) = fe.TrialFunctions(V_upv) (eta, q, xi) = fe.TestFunctions(V_upv) F = deformation_grad(u1) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) #I_1_iso, I_2_iso = invariants(F_iso)[0:2] W = material_mooney_rivlin(I_1, I_2, c_10, c_01) g = incompr_constr(J) L = -W P = first_piola_stress(L, F) G = incompr_stress(g, F) a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx a_dyn_p = inner(g, q) * dx a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner( P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx) a = a_dyn_u + a_dyn_p + a_dyn_v w1 = fe.Function(V_upv) sol = [] t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) fe.solve(a == 0, w1, bcs_u + bcs_p + bcs_v) if fe.norm(w1.vector()) > 1e7: print('ERROR: norm explosion') break # update initial values for next step w0.assign(w1) t += dt if show_plots: # plot result fe.plot(w0.sub(0), mode='displacement') plt.show() # save solutions sol.append(Solution(t=t)) sol[-1].upv.assign(w0) return sol, W, kappa
def steady(W, w, w_n, steady_relative_tolerance): """Check if solution has reached an approximately steady state.""" steady = False time_residual = fenics.Function(W) time_residual.assign(w - w_n) unsteadiness = fenics.norm(time_residual, "L2") / fenics.norm(w_n, "L2") phaseflow.helpers.print_once( "Unsteadiness (L2 norm of relative time residual), || w_{n+1} || / || w_n || = " + str(unsteadiness)) if (unsteadiness < steady_relative_tolerance): steady = True return steady
def write_results_table_row(self, table_filepath): with open(table_filepath, "a") as table_file: table_file.write( str(self.pressure_penalty_factor.__float__()) + "," \ + str(self.solid_viscosity.__float__()) + "," \ + str(self.temperature_rayleigh_number.__float__()) + "," \ + str(self.concentration_rayleigh_number.__float__()) + ", " \ + str(self.prandtl_number.__float__()) + ", " \ + str(self.stefan_number.__float__()) + ", " \ + str(self.schmidt_number.__float__()) + ", " \ + str(self.liquidus_slope.__float__()) + ", " \ + str(self.pure_liquidus_temperature.__float__()) + ", " \ + str(self.regularization_central_temperature_offset.__float__()) + ", " \ + str(self.regularization_smoothing_parameter.__float__()) + ", " \ + str(1./float(self.uniform_gridsize)) + ", " \ + str(self.timestep_size.__float__()) + ", " \ + str(self.time_order) + ", " \ + str(self.time) + ", ") solid_area = fenics.assemble(self.solid_area_integrand()) area_above_critical_phi = fenics.assemble( self.area_above_critical_phi_integrand()) solute_mass = fenics.assemble(self.solute_mass_integrand()) p, u, T, C = self.solution.leaf_node().split(deepcopy=True) phi = fenics.project(self.semi_phasefield(T=T, C=C), mesh=self.mesh.leaf_node()) Cbar = fenics.project(C * (1. - phi), mesh=self.mesh.leaf_node()) table_file.write( str(solid_area) + ", " \ + str(area_above_critical_phi) + ", " \ + str(solute_mass) + ", " \ + str(p.vector().min()) + ", " \ + str(p.vector().max()) + ", " \ + str(fenics.norm(u.vector(), "linf")) + ", " \ + str(T.vector().min()) + ", " \ + str(T.vector().max()) + ", " \ + str(Cbar.vector().min()) + ", " \ + str(Cbar.vector().max()) + ", " \ + str(phi.vector().min()) + ", " \ + str(phi.vector().max())) table_file.write("\n")
def test_run_invsigma(existing_temp_model, monkeypatch, setup_deps, request): setup_deps.set_case_dependency(request, ["test_run_eigendec"]) work_dir = existing_temp_model["work_dir"] toml_file = existing_temp_model["toml_filename"] # Switch to the working directory monkeypatch.chdir(work_dir) # Get expected values from the toml file params = config.ConfigParser(toml_file, top_dir=work_dir) expected_cntrl_sigma_norm = params.testing.expected_cntrl_sigma_norm expected_cntrl_sigma_prior_norm = params.testing.expected_cntrl_sigma_prior_norm EQReset() mdl_out = run_invsigma.run_invsigma(toml_file) cntrl_sigma_norm = norm(mdl_out.cntrl_sigma) cntrl_sigma_prior_norm = norm(mdl_out.cntrl_sigma_prior) if pytest.parallel: tol = 1e-6 else: tol = 1e-7 pytest.check_float_result(cntrl_sigma_norm, expected_cntrl_sigma_norm, work_dir, "expected_cntrl_sigma_norm", tol=tol) pytest.check_float_result(cntrl_sigma_prior_norm, expected_cntrl_sigma_prior_norm, work_dir, "expected_cntrl_sigma_prior_norm", tol=tol)
def __init__(me, function_space_V): me.V = function_space_V me.dof_coords = me.V.tabulate_dof_coordinates() f = fenics.Function(me.V) u = fenics.TrialFunction(me.V) v = fenics.TestFunction(me.V) a = fenics.inner(fenics.grad(u), fenics.grad(v)) * fenics.dx rhs = f * v * fenics.dx A = fenics.assemble(a) me.b = fenics.assemble(rhs) const_fct = fenics.Function(me.V) const_fct.interpolate(fenics.Constant(1.0)) const_vec = const_fct.vector() me.const_vec = const_vec / fenics.norm(const_vec) prec = fenics.PETScPreconditioner('hypre_amg') fenics.PETScOptions.set('pc_hypre_boomeramg_relax_type_coarse', 'jacobi') me._solver = fenics.PETScKrylovSolver('cg', prec) me._solver.set_operator(A)
def relaxation( displacement_fluid: Initial, velocity_fluid: Initial, displacement_solid: Initial, velocity_solid: Initial, functional_fluid_initial, functional_solid_initial, bilinear_form_fluid, functional_fluid, bilinear_form_solid, functional_solid, first_time_step, fluid: Space, solid: Space, interface: Space, param: Parameters, fluid_macrotimestep: MacroTimeStep, solid_macrotimestep: MacroTimeStep, adjoint, ): # Define initial values for relaxation method displacement_solid_new = Function(solid.function_space_split[0]) velocity_displacement_new = Function(solid.function_space_split[1]) number_of_iterations = 0 stop = False while not stop: number_of_iterations += 1 print( f"Current iteration of relaxation method: {number_of_iterations}") # Save old values displacement_solid_new.assign(displacement_solid.new) velocity_displacement_new.assign(velocity_solid.new) # Perform one iteration solve_problem( displacement_fluid, velocity_fluid, displacement_solid, velocity_solid, fluid, solid, solid_to_fluid, functional_fluid_initial, bilinear_form_fluid, functional_fluid, first_time_step, param, fluid_macrotimestep, adjoint, ) solve_problem( displacement_solid, velocity_solid, displacement_fluid, velocity_fluid, solid, fluid, fluid_to_solid, functional_solid_initial, bilinear_form_solid, functional_solid, first_time_step, param, solid_macrotimestep, adjoint, ) # Perform relaxation displacement_solid.new.assign( project( param.TAU * displacement_solid.new + (1.0 - param.TAU) * displacement_solid_new, solid.function_space_split[0], )) velocity_solid.new.assign( project( param.TAU * velocity_solid.new + (1.0 - param.TAU) * velocity_displacement_new, solid.function_space_split[1], )) # Define errors on the interface displacement_error = interpolate( project( displacement_solid_new - displacement_solid.new, solid.function_space_split[0], ), interface.function_space_split[0], ) displacement_error_linf = norm(displacement_error.vector(), "linf") velocity_error = interpolate( project( velocity_displacement_new - velocity_solid.new, solid.function_space_split[1], ), interface.function_space_split[1], ) velocity_error_linf = norm(velocity_error.vector(), "linf") error_linf = max(displacement_error_linf, velocity_error_linf) if number_of_iterations == 1: error_initial_linf = error_linf print(f"Absolute error on the interface: {error_linf}") print( f"Relative error on the interface: {error_linf / error_initial_linf}" ) # Check stop conditions if (error_linf < param.ABSOLUTE_TOLERANCE_RELAXATION or error_linf / error_initial_linf < param.RELATIVE_TOLERANCE_RELAXATION): print(f"Algorithm converged successfully after " f"{number_of_iterations} iterations") stop = True elif number_of_iterations == param.MAX_ITERATIONS_RELAXATION: print("Maximal number of iterations was reached.") stop = True number_of_iterations = -1 displacement_fluid.iterations.append(number_of_iterations) velocity_fluid.iterations.append(number_of_iterations) displacement_solid.iterations.append(number_of_iterations) displacement_solid.iterations.append(number_of_iterations) return
def half_exp_dyn(w0, dt=1.e-5, t_end=1.e-4, show_plots=False): u0 = w0.u p0 = w0.p v0 = w0.v bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_u, V_pv.sub(0), V_pv.sub(1), boundaries) F = deformation_grad(u0) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) #I_1_iso, I_2_iso = invariants(F_iso)[0:2] W = material_mooney_rivlin(I_1, I_2, c_10, c_01) g = incompr_constr(J) # Lagrange function (without constraint) L = -W P = first_piola_stress(L, F) G = incompr_stress(g, F) # a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx u1 = fe.TrialFunction(V_u) eta = fe.TestFunction(V_u) #u11 = fe.Function(V_u) #F1 = deformation_grad(u11) #g1 = incompr_constr(fe.det(F1)) #G1 = incompr_stress(g1, F1) (p1, v1) = fe.TrialFunctions(V_pv) (q, xi) = fe.TestFunctions(V_pv) a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v0, eta) * dx a_dyn_p = fe.tr(G * grad(v1)) * q * dx #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx) a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner( P, grad(xi)) * dx + inner(p1 * G, grad(xi)) * dx - inner(B, xi) * dx) a_u = fe.lhs(a_dyn_u) l_u = fe.rhs(a_dyn_u) a_pv = fe.lhs(a_dyn_p + a_dyn_v) l_pv = fe.rhs(a_dyn_p + a_dyn_v) u1 = fe.Function(V_u) pv1 = fe.Function(V_pv) sol = [] vol = fe.assemble(1. * dx) A_u = fe.assemble(a_u) A_pv = fe.assemble(a_pv) for bc in bcs_u: bc.apply(A_u) t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) # update displacement u L_u = fe.assemble(l_u) fe.solve(A_u, u1.vector(), L_u) u0.assign(u1) L_pv = fe.assemble(l_pv) for bc in bcs_p + bcs_v: bc.apply(A_pv, L_pv) fe.solve(A_pv, pv1.vector(), L_pv) if fe.norm(pv1.vector()) > 1e8: print('ERROR: norm explosion') break # update initial values for next step w0.u = u1 w0.pv = pv1 p0.assign(w0.p) v0.assign(w0.v) t += dt if show_plots: # plot result fe.plot(w0.sub(0), mode='displacement') plt.show() # save solutions sol.append(Solution(t=t)) sol[-1].upv.assign(w0) return sol, W
def explicit_relax_dyn(w0, kappa=1e5, dt=1.e-5, t_end=1.e-4, show_plots=False): (u0, p0, v0) = fe.split(w0) bcs_u, bcs_p, bcs_v = load_2d_muscle_bc(V_upv.sub(0), V_upv.sub(1), V_upv.sub(2), boundaries) kappa = fe.Constant(kappa) F = deformation_grad(u0) I_1, I_2, J = invariants(F) F_iso = isochronic_deformation_grad(F, J) #I_1_iso, I_2_iso = invariants(F_iso)[0:2] W = material_mooney_rivlin(I_1, I_2, c_10, c_01) + incompr_relaxation( p0, kappa) g = incompr_constr(J) # Lagrange function (without constraint) L = -W P = first_piola_stress(L, F) G = incompr_stress(g, F) (u1, p1, v1) = fe.TrialFunctions(V_upv) (eta, q, xi) = fe.TestFunctions(V_upv) a_dyn_u = inner(u1 - u0, eta) * dx - dt * inner(v1, eta) * dx a_dyn_p = (p1 - p0) * q * dx - dt * kappa * div(v1) * J * q * dx #a_dyn_v = rho*inner(v1-v0, xi)*dx + dt*(inner(P + p0*G, grad(xi))*dx - inner(B, xi)*dx) a_dyn_v = rho * inner(v1 - v0, xi) * dx + dt * (inner( P, grad(xi)) * dx + inner(p0 * G, grad(xi)) * dx - inner(B, xi) * dx) a = fe.lhs(a_dyn_u + a_dyn_p + a_dyn_v) l = fe.rhs(a_dyn_u + a_dyn_p + a_dyn_v) w1 = fe.Function(V_upv) w2 = fe.Function(V_upv) sol = [] vol = fe.assemble(1. * dx) t = 0 while t < t_end: print("progress: %f" % (100. * t / t_end)) A = fe.assemble(a) L = fe.assemble(l) for bc in bcs_u + bcs_p + bcs_v: bc.apply(A, L) fe.solve(A, w1.vector(), L) if fe.norm(w1.vector()) > 1e7: print('ERROR: norm explosion') break # update initial values for next step w0.assign(w1) t += dt if show_plots: # plot result fe.plot(w0.sub(0), mode='displacement') plt.show() # save solutions sol.append(Solution(t=t)) sol[-1].upv.assign(w0) return sol, W, kappa