def test_cook_finite_strain_linear_elasticity(self): # --- VALUES # ------- P_min = 1000. P_max = 5.e6 / (16.e-3) # P_min = 0.01 # P_max = 1. / 16. # time_steps = np.linspace(P_min, P_max, 20)[:-3] time_steps = np.linspace(P_min, P_max, 5) print(time_steps) iterations = 10 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [Load(volumetric_load, 0), Load(volumetric_load, 1)] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("RIGHT", pull, BoundaryType.PRESSURE, 1), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 1), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), ] # --- MESH mesh_file_path = "meshes/cook_quadrangles_1.msh" mesh_file_path = "meshes/cook_quadrangles_0.msh" mesh_file_path = "meshes/cook_triangles_0.msh" mesh_file_path = "meshes/cook_20.geof" # mesh_file_path = "meshes/cook_5.geof" # --- FIELD # displacement = Field(label="U", field_type=FieldType.DISPLACEMENT_SMALL_STRAIN_PLANE_STRAIN) displacement = Field(label="U", field_type=FieldType.DISPLACEMENT_LARGE_STRAIN_PLANE_STRAIN) # --- FINITE ELEMENT finite_element = FiniteElement( element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=displacement.euclidean_dimension, basis_type=BasisType.MONOMIAL, ) # --- PROBLEM p = Problem( mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-4, res_folder_path=get_current_res_folder_path() ) # --- MATERIAL parameters = {"YoungModulus": 70.0e9, "PoissonRatio": 0.4999} stabilization_parameter = 0.0005 * parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) # stabilization_parameter = parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path="behaviour/src/libBehaviour.so", library_name="Voce", hypothesis=mgis_bv.Hypothesis.PLANESTRAIN, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, ) # --- SOLVE solve_newton_2(p, mat, verbose=False, debug_mode=DebugMode.NONE) # solve_newton_exact(p, mat, verbose=False, debug_mode=DebugMode.NONE) res_folder = "res" from os import walk, path import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap def __plot(column: int): _, _, filenames = next(walk(res_folder)) for time_step_index in range(len(time_steps)): for filename in filenames: if "{}".format(time_step_index).zfill(6) in filename and "qdp" in filename: hho_file_path = path.join(res_folder, filename) with open(hho_file_path, "r") as hho_res_file: fig, ax0d = plt.subplots(nrows=1, ncols=1) c_hho = hho_res_file.readlines() field_label = c_hho[0].split(",")[column] number_of_points = len(c_hho) - 1 eucli_d = displacement.euclidean_dimension points = np.zeros((eucli_d, number_of_points), dtype=real) field_vals = np.zeros((number_of_points,), dtype=real) for l_count, line in enumerate(c_hho[1:]): x_coordinates = float(line.split(",")[0]) y_coordinates = float(line.split(",")[1]) field_value = float(line.split(",")[column]) points[0, l_count] += x_coordinates points[1, l_count] += y_coordinates field_vals[l_count] += field_value x, y = points colors = [(0, 0, 1), (0, 1, 1), (0, 1, 0), (1, 1, 0), (1, 0, 0)] perso = LinearSegmentedColormap.from_list("perso", colors, N=1000) vmin = min(field_vals[:]) vmax = max(field_vals[:]) # vmin = -3900.e6 # vmax = 627.e6 levels = np.linspace(vmin, vmax, 50, endpoint=True) ticks = np.linspace(vmin, vmax, 10, endpoint=True) datad = ax0d.tricontourf(x, y, field_vals[:], cmap=perso, levels=levels) ax0d.get_xaxis().set_visible(False) ax0d.get_yaxis().set_visible(False) ax0d.set_xlabel("map of the domain $\Omega$") cbar = fig.colorbar(datad, ax=ax0d, ticks=ticks) cbar.set_label("{}".format(field_label), rotation=270, labelpad=15.0) # plt.savefig("/home/dsiedel/Projects/pythhon/plots/{}.png".format(time_step)) plt.show() __plot(15)
def test_square_finite_strain_isotropic_voce_hardening(self): # --- VALUES spacing = 3 time_steps_1 = np.linspace(0.0, 7.0e-3, spacing) time_steps_2 = np.linspace(7.0e-3, -1.0e-2, spacing) time_steps_3 = np.linspace(-1.0e-2, 2.0e-2, spacing) time_steps_4 = np.linspace(2.0e-2, -3.0e-2, spacing) time_steps_5 = np.linspace(-3.0e-2, 4.0e-2, spacing) time_steps = [] for ts in [ time_steps_1, time_steps_2[1:], time_steps_3[1:], time_steps_4[1:], time_steps_5[1:] ]: # time_steps += list(np.sqrt(2.)*ts) time_steps += list(ts) time_steps = np.array(time_steps) time_steps = np.linspace(0.0, 4.0e-2, 11, endpoint=True) iterations = 100 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [Load(volumetric_load, 0), Load(volumetric_load, 1)] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("RIGHT", pull, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("BOTTOM", fixed, BoundaryType.DISPLACEMENT, 1), ] # --- MESH mesh_file_path = ( # "meshes/triang_r.geof" # "meshes/triang_2.geof" # "meshes/square_1.geof" # "meshes/pentag_1.geof" # "meshes/triangles_0.msh" "meshes/quadrangles_2.msh" # "meshes/quadrangles_0.msh" # "meshes/triangles_3.msh" # "meshes/triang_3.geof" ) # --- FIELD displacement = Field( label="U", field_type=FieldType.DISPLACEMENT_LARGE_STRAIN_PLANE_STRAIN) # --- FINITE ELEMENT finite_element = FiniteElement( element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=displacement.euclidean_dimension, basis_type=BasisType.MONOMIAL, ) # --- PROBLEM p = Problem(mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-4, res_folder_path=get_current_res_folder_path()) # --- MATERIAL parameters = { "YoungModulus": 70.0e9, "PoissonRatio": 0.34, "HardeningSlope": 10.0e9, "YieldStress": 300.0e6 } stabilization_parameter = parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path="behaviour/src/libBehaviour.so", library_name="Voce", hypothesis=mgis_bv.Hypothesis.PLANESTRAIN, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, # finite_strains=False ) # --- SOLVE solve_newton_2(p, mat, verbose=False) # solve_newton_exact(p, mat, verbose=False) # --- POST PROCESSING from pp.plot_data import plot_data mtest_file_path = "mtest/finite_strain_isotropic_voce_hardening.res" hho_res_dir_path = "res" number_of_time_steps = len(time_steps) m_x_inedx = 1 m_y_index = 6 d_x_inedx = 4 d_y_inedx = 9 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 7 d_x_inedx = 4 d_y_inedx = 10 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 8 d_x_inedx = 4 d_y_inedx = 11 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 9 d_x_inedx = 4 d_y_inedx = 12 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx)
def solve_newton_2(problem: Problem, material: Material, verbose: bool = False, debug_mode: DebugMode = DebugMode.NONE): time_step_index_count = 0 clean_res_dir(problem.res_folder_path) problem.create_output(problem.res_folder_path) _dx = problem.field.field_dimension _fk = problem.finite_element.face_basis_k.dimension _cl = problem.finite_element.cell_basis_l.dimension external_forces_coefficient = 1.0 normalization_lagrange_coefficient = material.lagrange_parameter # ---------------------------------------------------------------------------------------------------------- # SET SYSTEM SIZE # ---------------------------------------------------------------------------------------------------------- _constrained_system_size, _system_size = problem.get_total_system_size() faces_unknown_vector = np.zeros((_constrained_system_size), dtype=real) faces_unknown_vector_previous_step = np.zeros((_constrained_system_size), dtype=real) residual_values = [] time_step_temp = problem.time_steps[0] initial_time_steps = [ff for ff in problem.time_steps] for time_step_index, time_step in enumerate(problem.time_steps): local_time_steps = [time_step] for local_time_step_index, local_time_step in enumerate( local_time_steps): print("0K") # --- SET TEMPERATURE material.set_temperature() # --- PRINT DATA print( "----------------------------------------------------------------------------------------------------" ) print("TIME_STEP : {} | LOAD_VALUE : {}".format( time_step_index, time_step)) # --- WRITE RES FILES # if time_step in initial_time_steps: # file_suffix = "{}".format(time_step_index).zfill(6) # problem.create_vertex_res_files(problem.res_folder_path, file_suffix) # problem.create_quadrature_points_res_files(problem.res_folder_path, file_suffix, material) for iteration in range(problem.number_of_iterations): # -------------------------------------------------------------------------------------------------- # SET SYSTEM MATRIX AND VECTOR # -------------------------------------------------------------------------------------------------- tangent_matrix = np.zeros( (_constrained_system_size, _constrained_system_size), dtype=real) residual = np.zeros((_constrained_system_size), dtype=real) # -------------------------------------------------------------------------------------------------- # SET TIME INCREMENT # -------------------------------------------------------------------------------------------------- if time_step_index == 0: _dt = time_step else: _dt = time_step - problem.time_steps[time_step_index - 1] _dt = np.float64(_dt) # _dt = 0.0 # _dt = np.float64(0.0) # -------------------------------------------------------------------------------------------------- # FOR ELEMENT LOOP # -------------------------------------------------------------------------------------------------- _qp = 0 stab_coef = 1.0 iter_face_constraint = 0 for _element_index, element in enumerate(problem.elements): cell_quadrature_size = element.cell.get_quadrature_size( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) cell_quadrature_points = element.cell.get_quadrature_points( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) cell_quadrature_weights = element.cell.get_quadrature_weights( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) x_c = element.cell.get_centroid() h_c = element.cell.get_diameter() _nf = len(element.faces) _c0_c = _dx * _cl # --- INITIALIZE MATRIX AND VECTORS element_stiffness_matrix = np.zeros( (element.element_size, element.element_size), dtype=real) element_internal_forces = np.zeros((element.element_size, ), dtype=real) element_external_forces = np.zeros((element.element_size, ), dtype=real) # --- RUN OVER EACH QUADRATURE POINT for _qc in range(cell_quadrature_size): _w_q_c = cell_quadrature_weights[_qc] # _w_q_c = np.abs(cell_quadrature_weights[_qc]) _x_q_c = cell_quadrature_points[:, _qc] # --- COMPUTE STRAINS AND SET THEM IN THE BEHAVIOUR LAW transformation_gradient = element.get_transformation_gradient( faces_unknown_vector, _qc) material.mat_data.s1.gradients[ _qp] = transformation_gradient # --- INTEGRATE BEHAVIOUR LAW integ_res = mgis_bv.integrate(material.mat_data, material.integration_type, _dt, _qp, (_qp + 1)) # stored_energies', 'dissipated_energies', 'internal_state_variables # print(material.mat_data.s1.internal_state_variables) # --- VOLUMETRIC FORCES v = problem.finite_element.cell_basis_l.evaluate_function( _x_q_c, x_c, h_c) for load in problem.loads: vl = _w_q_c * v * load.function(time_step, _x_q_c) _re0 = load.direction * _cl _re1 = (load.direction + 1) * _cl element_external_forces[_re0:_re1] += vl # --- COMPUTE STIFFNESS MATRIX CONTRIBUTION AT QUADRATURE POINT element_stiffness_matrix += _w_q_c * ( element.gradients_operators[_qc].T @ material.mat_data. K[_qp] @ element.gradients_operators[_qc]) # --- COMPUTE STIFFNESS MATRIX CONTRIBUTION AT QUADRATURE POINT element_internal_forces += _w_q_c * ( element.gradients_operators[_qc].T @ material.mat_data.s1.thermodynamic_forces[_qp]) _qp += 1 if debug_mode == DebugMode.LIGHT: print("ELEM : {} | INTERNAL_FORCES_BEFORE STAB : \n {}". format(_element_index, element_internal_forces)) if verbose: print("ELEM : {} | INTERNAL_FORCES_BEFORE STAB : \n {}". format(_element_index, element_internal_forces)) # --- STAB PARAMETER CHANGE stab_param = stab_coef * material.stabilization_parameter # --- ADDING STABILIZATION CONTRIBUTION AT THE ELEMENT LEVEL element_stiffness_matrix += stab_param * element.stabilization_operator # element_stiffness_matrix -= stab_param * element.stabilization_operator # --- ADDING STABILIZATION CONTRIBUTION AT THE ELEMENT LEVEL element_internal_forces += ( stab_param * element.stabilization_operator @ element.get_element_unknown_vector(faces_unknown_vector)) # element_internal_forces -= ( # stab_param # * element.stabilization_operator # @ element.get_element_unknown_vector(problem.field, problem.finite_element, faces_unknown_vector) # ) # if verbose: # print( # "ELEM : {} | INTERNAL_FORCES_AFTER STAB : \n {}".format(_element_index, element_internal_forces) # ) # _iv0 = _element_index * len(element.cell.quadrature_weights) # _iv1 = (_element_index + 1) * len(element.cell.quadrature_weights) # print( # "ELEM : {} | DISPLACEMENT S0 : \n {}".format( # _element_index, # element.get_element_unknown_vector( # problem.field, problem.finite_element, faces_unknown_vector_previous_step # ), # ) # ) # print( # "ELEM : {} | GRADIENTS S0 : \n {}".format( # _element_index, material.mat_data.s0.gradients[_iv0:_iv1] # ) # ) # print( # "ELEM : {} | DISPLACEMENT S1 : \n {}".format( # _element_index, # element.get_element_unknown_vector( # problem.field, problem.finite_element, faces_unknown_vector # ), # ) # ) # print( # "ELEM : {} | GRADIENTS S1 : \n {}".format( # _element_index, material.mat_data.s1.gradients[_iv0:_iv1] # ) # ) # if not material.behaviour_name == "Elasticity": # print( # "ELEM : {} | INTERNAL_STATE_VARIABLES S0 : \n {}".format( # _element_index, material.mat_data.s0.internal_state_variables[_iv0:_iv1] # ) # ) # print( # "ELEM : {} | INTERNAL_STATE_VARIABLES S1 : \n {}".format( # _element_index, material.mat_data.s1.internal_state_variables[_iv0:_iv1] # ) # ) # --- BOUNDARY CONDITIONS for boundary_condition in problem.boundary_conditions: # --- DISPLACEMENT CONDITIONS if boundary_condition.boundary_type == BoundaryType.DISPLACEMENT: for f_local, f_global in enumerate( element.faces_indices): if f_global in problem.mesh.faces_boundaries_connectivity[ boundary_condition.boundary_name]: _l0 = _system_size + iter_face_constraint * _fk _l1 = _system_size + (iter_face_constraint + 1) * _fk _c0 = _cl * _dx + ( f_local * _dx * _fk) + boundary_condition.direction * _fk _c1 = _cl * _dx + (f_local * _dx * _fk) + ( boundary_condition.direction + 1) * _fk _r0 = f_global * _fk * _dx + _fk * boundary_condition.direction _r1 = f_global * _fk * _dx + _fk * ( boundary_condition.direction + 1) # ------- # face_displacement = element_unknown_increment[_r0:_r1] # face_displacement = np.copy(element_unknown_increment[_c0:_c1]) # face_displacement = element_unknown_increment[_c0:_c1] face_lagrange = faces_unknown_vector[_l0:_l1] face_displacement = faces_unknown_vector[ _r0:_r1] _m_psi_psi_face = np.zeros((_fk, _fk), dtype=real) _v_face_imposed_displacement = np.zeros( (_fk, ), dtype=real) face = element.faces[f_local] x_f = face.get_centroid() h_f = face.get_diameter() face_rot = face.get_rotation_matrix() face_quadrature_size = face.get_quadrature_size( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_points = face.get_quadrature_points( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_weights = face.get_quadrature_weights( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) for _qf in range(face_quadrature_size): # _h_f = element.faces[f_local].shape.diameter # _x_f = element.faces[f_local].shape.centroid _x_q_f = face_quadrature_points[:, _qf] _w_q_f = face_quadrature_weights[_qf] _s_q_f = (face_rot @ _x_q_f)[:-1] _s_f = (face_rot @ x_f)[:-1] # v = problem.finite_element.face_basis_k.evaluate_function( # _x_q_f, # element.faces[f_local].shape.centroid, # element.faces[f_local].shape.diameter, # ) v = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) _v_face_imposed_displacement += ( _w_q_f * v * boundary_condition.function( time_step, _x_q_f)) # _m_psi_psi_face += blocks.get_face_mass_matrix_in_face( # element.faces[f_local], # problem.finite_element.face_basis_k, # problem.finite_element.face_basis_k, # _x_q_f, # _w_q_f, # ) _psi_k = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) _m_psi_psi_face += _w_q_f * np.tensordot( _psi_k, _psi_k, axes=0) _m_psi_psi_face_inv = np.linalg.inv( _m_psi_psi_face) if debug_mode == 0: print( "FACE MASS MATRIX IN DIRICHLET BOUND COND :" ) print("{}".format( np.linalg.cond(_m_psi_psi_face))) imposed_face_displacement = _m_psi_psi_face_inv @ _v_face_imposed_displacement face_displacement_difference = face_displacement - imposed_face_displacement # print(face_lagrange) # --- LAGRANGE INTERNAL FORCES PART element_internal_forces[ _c0: _c1] += normalization_lagrange_coefficient * face_lagrange # --- LAGRANGE MULTIPLIERS PART # residual[_l0:_l1] += ( # normalization_lagrange_coefficient * face_displacement_difference # ) residual[ _l0: _l1] -= normalization_lagrange_coefficient * face_displacement_difference # --- LAGRANGE MATRIX PART tangent_matrix[ _l0:_l1, _r0: _r1] += normalization_lagrange_coefficient * np.eye( _fk, dtype=real) tangent_matrix[ _r0:_r1, _l0: _l1] += normalization_lagrange_coefficient * np.eye( _fk, dtype=real) # --- SET EXTERNAL FORCES COEFFICIENT lagrange_external_forces = ( normalization_lagrange_coefficient * imposed_face_displacement) if np.max(np.abs(lagrange_external_forces) ) > external_forces_coefficient: external_forces_coefficient = np.max( np.abs(lagrange_external_forces)) iter_face_constraint += 1 elif boundary_condition.boundary_type == BoundaryType.PRESSURE: for f_local, f_global in enumerate( element.faces_indices): if f_global in problem.mesh.faces_boundaries_connectivity[ boundary_condition.boundary_name]: face = element.faces[f_local] x_f = face.get_centroid() h_f = face.get_diameter() face_rot = face.get_rotation_matrix() face_quadrature_size = face.get_quadrature_size( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_points = face.get_quadrature_points( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_weights = face.get_quadrature_weights( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) for _qf in range(face_quadrature_size): # _h_f = element.faces[f_local].shape.diameter # _x_f = element.faces[f_local].shape.centroid _x_q_f = face_quadrature_points[:, _qf] _w_q_f = face_quadrature_weights[_qf] _s_q_f = (face_rot @ _x_q_f)[:-1] _s_f = (face_rot @ x_f)[:-1] # for qf in range(len(element.faces[f_local].quadrature_weights)): # # _h_f = element.faces[f_local].shape.diameter # # _x_f = element.faces[f_local].shape.centroid # _x_q_f = face_quadrature_points[:, _qf] # _w_q_f = face_quadrature_weights[_qf] # _s_q_f = (element.faces[f_local].mapping_matrix @ _x_q_f)[:-1] # _s_f = (element.faces[f_local].mapping_matrix @ _x_f)[:-1] # v = problem.finite_element.face_basis_k.evaluate_function( # _x_q_f, # element.faces[f_local].shape.centroid, # element.faces[f_local].shape.diameter, # ) v = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) # _x_q_f = element.faces[f_local].quadrature_points[:, qf] # _w_q_f = element.faces[f_local].quadrature_weights[qf] # v = problem.finite_element.face_basis_k.evaluate_function( # _x_q_f, # element.faces[f_local].shape.centroid, # element.faces[f_local].shape.diameter, # ) vf = _w_q_f * v * boundary_condition.function( time_step, _x_q_f) _c0 = _dx * _cl + f_local * _dx * _fk + boundary_condition.direction * _fk _c1 = _dx * _cl + f_local * _dx * _fk + ( boundary_condition.direction + 1) * _fk # _r0 = f_global * _fk * _dx + _fk * boundary_condition.direction # _r1 = f_global * _fk * _dx + _fk * (boundary_condition.direction + 1) element_external_forces[_c0:_c1] += vf # --- COMPUTE RESIDUAL AFTER VOLUMETRIC CONTRIBUTION element_residual = element_internal_forces - element_external_forces if verbose: print("ELEM : {} | INTERNAL_FORCES_END : \n {}".format( _element_index, element_internal_forces)) print("ELEM : {} | ELEMENT_RESIDUAL : \n {}".format( _element_index, element_residual)) # -------------------------------------------------------------------------------------------------- # CONDENSATION # -------------------------------------------------------------------------------------------------- m_cell_cell = element_stiffness_matrix[:_c0_c, :_c0_c] m_cell_faces = element_stiffness_matrix[:_c0_c, _c0_c:] m_faces_cell = element_stiffness_matrix[_c0_c:, :_c0_c] m_faces_faces = element_stiffness_matrix[_c0_c:, _c0_c:] # v_cell = element_residual[:_c0_c] # v_faces = element_residual[_c0_c:] v_cell = -element_residual[:_c0_c] v_faces = -element_residual[_c0_c:] _condtest = np.linalg.cond(m_cell_cell) m_cell_cell_inv = np.linalg.inv(m_cell_cell) if debug_mode == 0: print("TANGENT MATRIX IN CONDENSATION COND :") print("{}".format(np.linalg.cond(m_cell_cell))) # ge = m_faces_cell @ m_cell_cell_inv # gd = (m_faces_cell @ m_cell_cell_inv) @ m_cell_faces K_cond = m_faces_faces - ( (m_faces_cell @ m_cell_cell_inv) @ m_cell_faces) R_cond = v_faces - (m_faces_cell @ m_cell_cell_inv) @ v_cell # --- SET CONDENSATION/DECONDENSATION MATRICES element.m_cell_cell_inv = m_cell_cell_inv element.m_cell_faces = m_cell_faces element.v_cell = v_cell # --- ASSEMBLY for _i_local, _i_global in enumerate(element.faces_indices): _rg0 = _i_global * (_fk * _dx) _rg1 = (_i_global + 1) * (_fk * _dx) _re0 = _i_local * (_fk * _dx) _re1 = (_i_local + 1) * (_fk * _dx) residual[_rg0:_rg1] += R_cond[_re0:_re1] for _j_local, _j_global in enumerate( element.faces_indices): _cg0 = _j_global * (_fk * _dx) _cg1 = (_j_global + 1) * (_fk * _dx) _ce0 = _j_local * (_fk * _dx) _ce1 = (_j_local + 1) * (_fk * _dx) tangent_matrix[_rg0:_rg1, _cg0:_cg1] += K_cond[_re0:_re1, _ce0:_ce1] # --- SET EXTERNAL FORCES COEFFICIENT if np.max(np.abs(element_external_forces) ) > external_forces_coefficient: external_forces_coefficient = np.max( np.abs(element_external_forces)) # -------------------------------------------------------------------------------------------------- # RESIDUAL EVALUATION # -------------------------------------------------------------------------------------------------- if external_forces_coefficient == 0.0: external_forces_coefficient = 1.0 residual_evaluation = np.max( np.abs(residual)) / external_forces_coefficient print("ITER : {} | RES_MAX : {}".format( str(iteration).zfill(4), residual_evaluation)) # print("ITER : {} | =====================================================================".format(str(iteration).zfill(4))) # residual_values.append(residual_evaluation) # if residual_evaluation < problem.tolerance: if residual_evaluation < problem.tolerance: # ---------------------------------------------------------------------------------------------- # UPDATE INTERNAL VARIABLES # ---------------------------------------------------------------------------------------------- mgis_bv.update(material.mat_data) print("ITERATIONS : {}".format(iteration + 1)) file_suffix = "{}".format(time_step_index).zfill(6) problem.create_vertex_res_files(problem.res_folder_path, file_suffix) problem.create_quadrature_points_res_files( problem.res_folder_path, file_suffix, material) problem.write_vertex_res_files(problem.res_folder_path, file_suffix, faces_unknown_vector) problem.write_quadrature_points_res_files( problem.res_folder_path, file_suffix, material, faces_unknown_vector) # problem.create_output(problem.res_folder_path) problem.fill_quadrature_stress_output(problem.res_folder_path, "CAUCHY_STRESS", time_step_index_count, time_step, material) problem.fill_quadrature_strain_output(problem.res_folder_path, "STRAIN", time_step_index_count, time_step, material) # problem.close_output(problem.res_folder_path) time_step_index_count += 1 faces_unknown_vector_previous_step = np.copy( faces_unknown_vector) for element in problem.elements: element.cell_unknown_vector_backup = np.copy( element.cell_unknown_vector) residual_values.append(residual_evaluation) time_step_temp = time_step + 0. break elif iteration == problem.number_of_iterations - 1: problem.time_steps.insert(time_step_index + 1, (time_step + time_step_temp) / 2.) faces_unknown_vector = np.copy( faces_unknown_vector_previous_step) for element in problem.elements: # element.cell_unknown_vector = np.zeros((_cl * _dx,)) element.cell_unknown_vector = np.copy( element.cell_unknown_vector_backup) break else: # ---------------------------------------------------------------------------------------------- # SOLVE SYSTEM # ---------------------------------------------------------------------------------------------- if debug_mode == 0: print("K GLOBAL COND") print("{}".format(np.linalg.cond(tangent_matrix))) # sparse_global_matrix = csr_matrix(-tangent_matrix) sparse_global_matrix = csr_matrix(tangent_matrix) correction = spsolve(sparse_global_matrix, residual) # print("CORRECTION :") # print(correction) # correction = np.linalg.solve(-tangent_matrix, residual) faces_unknown_vector += correction if verbose: print( "R_K_RES : \n {}".format(residual - tangent_matrix @ correction)) print("R_K_RES_NORMALIZED : \n {}".format( (residual - tangent_matrix @ correction) / external_forces_coefficient)) # ---------------------------------------------------------------------------------------------- # DECONDENSATION # ---------------------------------------------------------------------------------------------- for element in problem.elements: _nf = len(element.faces) # _c0_c = _dx * _cl # --- DECONDENSATION - GET ELEMENT UNKNOWN CORRECTION face_correction = np.zeros((_nf * _fk * _dx), dtype=real) # element_correction = np.zeros((element.element_size,)) for _i_local, _i_global in enumerate( element.faces_indices): _c0_fg = _i_global * (_fk * _dx) _c1_fg = (_i_global + 1) * (_fk * _dx) # _c0_fl = (_dx * _cl) + _i_local * (_fk * _dx) # _c1_fl = (_dx * _cl) + (_i_local + 1) * (_fk * _dx) _c0_fl = _i_local * (_fk * _dx) _c1_fl = (_i_local + 1) * (_fk * _dx) # element_correction[_c0_fl:_c1_fl] += correction[_c0_fg:_c1_fg] face_correction[_c0_fl:_c1_fl] += correction[ _c0_fg:_c1_fg] # element_correction[:_c0_c] = element.m_cell_cell_inv @ ( # element.v_cell - element.m_cell_faces @ element_correction[_c0_c:] # ) cell_correction = element.m_cell_cell_inv @ ( element.v_cell - element.m_cell_faces @ face_correction) # --- ADDING CORRECTION TO CURRENT DISPLACEMENT element.cell_unknown_vector += cell_correction plt.plot(range(len(residual_values)), residual_values, label="residual") plt.plot(range(len(residual_values)), [problem.tolerance for local_i in range(len(residual_values))], label="tolerance") plt.ylabel("resiudal after convergence") plt.xlabel("time step index") plt.title("evolution of the residual") plt.legend() plt.gcf().subplots_adjust(left=0.15) plt.show() return
def test_problem_build(self, verbose=True): # --- VALUES p_min = 0.0 p_max = 1. / 16. time_steps = np.linspace(p_min, p_max, 10) iterations = 100 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [Load(volumetric_load, 0), Load(volumetric_load, 1)] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("RIGHT", pull, BoundaryType.PRESSURE, 1), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 1), ] # --- MESH mesh_file_path = ("meshes/triang_r.geof") # --- FIELD displacement = Field( label="U", field_type=FieldType.DISPLACEMENT_SMALL_STRAIN_PLANE_STRAIN, ) # --- FINITE ELEMENT finite_element = FiniteElement(element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=2, basis_type=BasisType.MONOMIAL) # --- PROBLEM p = Problem(mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-4, res_folder_path=get_current_res_folder_path()) # --- MATERIAL parameters = {"YoungModulus": 70.0e9, "PoissonRatio": 0.34} stabilization_parameter = parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path= "../../test_mechanics/test_element/2D/test_2D_small_strain_linear_elasticity/behaviour/src/libBehaviour.so", library_name="Elasticity", hypothesis=mgis_bv.Hypothesis.PLANESTRAIN, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, # finite_strains=False ) # --- SOLVE solve_newton_2(p, mat)
def test_sphere_finite_strain(self): # --- VALUES time_steps = np.linspace(0.0, 6.0e-3, 150) iterations = 100 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [ Load(volumetric_load, 0), Load(volumetric_load, 1), Load(volumetric_load, 2) ] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("BOTTOM", pull, BoundaryType.DISPLACEMENT, 1), BoundaryCondition("RIGHT", fixed, BoundaryType.DISPLACEMENT, 2), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("INTERIOR", fixed, BoundaryType.PRESSURE, 0), ] # --- MESH mesh_file_path = "meshes/sphere_triangles_0.msh" # mesh_file_path = "meshes/ssna.msh" # mesh_file_path = "meshes/ssna_quad.msh" # mesh_file_path = "meshes/ssna303_triangles_1.msh" # --- FIELD displacement = Field(label="U", field_type=FieldType.DISPLACEMENT_LARGE_STRAIN) # --- FINITE ELEMENT finite_element = FiniteElement( element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=displacement.euclidean_dimension, basis_type=BasisType.MONOMIAL, ) # --- PROBLEM p = Problem(mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-4, res_folder_path=get_current_res_folder_path()) # --- MATERIAL parameters = { "YoungModulus": 70.0e9, "PoissonRatio": 0.34, "HardeningSlope": 10.0e9, "YieldStress": 300.0e6 } # stabilization_parameter = 0.001 * parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) stabilization_parameter = parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path="behaviour/src/libBehaviour.so", library_name="Voce", # library_name="FiniteStrainIsotropicLinearHardeningPlasticity", hypothesis=mgis_bv.Hypothesis.TRIDIMENSIONAL, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, ) # --- SOLVE solve_newton_2(p, mat, verbose=False, debug_mode=DebugMode.NONE) # solve_newton_exact(p, mat, verbose=False, debug_mode=DebugMode.NONE) from pp.plot_ssna import plot_det_f
def test_square_small_strain_linear_elasticity(self): # --- VALUES u_min = 0.0 u_max = 0.008 time_steps = np.linspace(u_min, u_max, 9) iterations = 100 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [Load(volumetric_load, 0), Load(volumetric_load, 1)] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("RIGHT", pull, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), BoundaryCondition("BOTTOM", fixed, BoundaryType.DISPLACEMENT, 1), ] # --- MESH mesh_file_path = ( # "meshes/triang_r.geof" # "meshes/triang_2.geof" # "meshes/square_1.geof" # "meshes/pentag_1.geof" # "meshes/triangles_0.msh" "meshes/quadrangles_0.msh" # "meshes/triang_3.geof" ) # --- FIELD displacement = Field( label="U", field_type=FieldType.DISPLACEMENT_SMALL_STRAIN_PLANE_STRAIN) # --- FINITE ELEMENT finite_element = FiniteElement( element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=displacement.euclidean_dimension, basis_type=BasisType.MONOMIAL, ) # --- PROBLEM p = Problem(mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-4, res_folder_path=get_current_res_folder_path()) # --- MATERIAL parameters = {"YoungModulus": 70.0e9, "PoissonRatio": 0.34} stabilization_parameter = parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path="behaviour/src/libBehaviour.so", library_name="Elasticity", hypothesis=mgis_bv.Hypothesis.PLANESTRAIN, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, ) # --- SOLVE solve_newton_2(p, mat, verbose=False) # solve_newton_exact(p, mat, verbose=False) # --- POST PROCESSING from pp.plot_data import plot_data mtest_file_path = "mtest/small_strain_linear_elasticity.res" hho_res_dir_path = "res" number_of_time_steps = len(time_steps) m_x_inedx = 1 m_y_index = 5 d_x_inedx = 4 d_y_inedx = 8 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 6 d_x_inedx = 4 d_y_inedx = 9 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 7 d_x_inedx = 4 d_y_inedx = 10 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx) m_x_inedx = 1 m_y_index = 8 d_x_inedx = 4 d_y_inedx = 11 plot_data(mtest_file_path, hho_res_dir_path, number_of_time_steps, m_x_inedx, m_y_index, d_x_inedx, d_y_inedx)
def solve_newton_exact(problem: Problem, material: Material, verbose: bool = False, debug_mode: DebugMode = DebugMode.NONE): """ Args: material: Returns: """ clean_res_dir(problem.res_folder_path) _dx = problem.field.field_dimension _fk = problem.finite_element.face_basis_k.dimension _cl = problem.finite_element.cell_basis_l.dimension external_forces_coefficient = 1.0 normalization_lagrange_coefficient = material.lagrange_parameter # ---------------------------------------------------------------------------------------------------------- # SET SYSTEM SIZE # ---------------------------------------------------------------------------------------------------------- _constrained_system_size, _system_size = problem.get_total_system_size() faces_unknown_vector = np.zeros((_constrained_system_size), dtype=real) faces_unknown_vector_previous_step = np.zeros((_constrained_system_size), dtype=real) residual_values = [] correction = np.zeros((_constrained_system_size), dtype=real) for time_step_index, time_step in enumerate(problem.time_steps): # --- SET TEMPERATURE material.set_temperature() # --- PRINT DATA print( "----------------------------------------------------------------------------------------------------" ) print("TIME_STEP : {} | LOAD_VALUE : {}".format( time_step_index, time_step)) # --- WRITE RES FILES file_suffix = "{}".format(time_step_index).zfill(6) problem.create_vertex_res_files(problem.res_folder_path, file_suffix) problem.create_quadrature_points_res_files(problem.res_folder_path, file_suffix, material) # correction = np.zeros((_constrained_system_size),dtype=real) # --- RESET DISPLACEMENT reset_displacement = False if reset_displacement: faces_unknown_vector = np.zeros((_constrained_system_size), dtype=real) for element in problem.elements: element.cell_unknown_vector = np.zeros((_dx * _cl, ), dtype=real) for iteration in range(problem.number_of_iterations): # -------------------------------------------------------------------------------------------------- # SET SYSTEM MATRIX AND VECTOR # -------------------------------------------------------------------------------------------------- tangent_matrix = np.zeros( (_constrained_system_size, _constrained_system_size), dtype=real) residual = np.zeros((_constrained_system_size), dtype=real) # -------------------------------------------------------------------------------------------------- # SET TIME INCREMENT # -------------------------------------------------------------------------------------------------- if time_step_index == 0: _dt = time_step else: _dt = time_step - problem.time_steps[time_step_index - 1] _dt = np.float64(_dt) # -------------------------------------------------------------------------------------------------- # FOR ELEMENT LOOP # -------------------------------------------------------------------------------------------------- _qp = 0 stab_coef = 1.0 stab_inf = np.inf iter_face_constraint = 0 if False: for element in problem.elements: for _qc in range(len(element.cell.quadrature_weights)): _w_q_c = element.cell.quadrature_weights[_qc] _x_q_c = element.cell.quadrature_points[:, _qc] # --- COMPUTE STRAINS AND SET THEM IN THE BEHAVIOUR LAW transformation_gradient = element.get_transformation_gradient( problem.field, problem.finite_element, faces_unknown_vector, _qc) material.mat_data.s1.gradients[ _qp] = transformation_gradient # --- INTEGRATE BEHAVIOUR LAW integ_res = mgis_bv.integrate( material.mat_data, material.integration_type, _dt, _qp, (_qp + 1)) eigen_values = np.linalg.eig( material.mat_data.K[_qp])[0] stab_elem = np.min( eigen_values) / material.stabilization_parameter if stab_elem < stab_inf and stab_elem > 1.0: stab_inf = stab_elem stab_coef = stab_elem _qp += 1 mgis_bv.revert(material.mat_data) _qp = 0 for _element_index, element in enumerate(problem.elements): cell_quadrature_size = element.cell.get_quadrature_size( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) cell_quadrature_points = element.cell.get_quadrature_points( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) cell_quadrature_weights = element.cell.get_quadrature_weights( problem.finite_element.construction_integration_order, quadrature_type=problem.quadrature_type) x_c = element.cell.get_centroid() h_c = element.cell.get_diameter() print("ELEMENT : {}".format(_element_index)) # --- GET FACES LOCAL CORRECTION local_faces_correction = np.zeros( (len(element.faces) * _dx * _fk), dtype=real) for _f_local, _f_global in enumerate(element.faces_indices): local_faces_correction[_f_local * _dx * _fk:(_f_local + 1) * _dx * _fk] += ( correction[_f_global * _dx * _fk:(_f_global + 1) * _dx * _fk]) # --- LOCAL NEWTON number_of_local_iterations = 20 # local_tolerance = problem.tolerance local_tolerance = 1.e-4 R_cell_value_previous = np.inf for _local_iteration in range(number_of_local_iterations): _nf = len(element.faces) _c0_c = _dx * _cl # --- INITIALIZE MATRIX AND VECTORS element_stiffness_matrix = np.zeros( (element.element_size, element.element_size), dtype=real) element_internal_forces = np.zeros( (element.element_size, ), dtype=real) element_external_forces = np.zeros( (element.element_size, ), dtype=real) # --- RUN OVER EACH QUADRATURE POINT _local_qp = 0 for _qc in range(cell_quadrature_size): _w_q_c = cell_quadrature_weights[_qc] _x_q_c = cell_quadrature_points[:, _qc] # --- COMPUTE STRAINS AND SET THEM IN THE BEHAVIOUR LAW transformation_gradient = element.get_transformation_gradient( faces_unknown_vector, _qc) material.mat_data.s1.gradients[ _qp] = transformation_gradient # --- INTEGRATE BEHAVIOUR LAW integ_res = mgis_bv.integrate( material.mat_data, material.integration_type, _dt, _qp, (_qp + 1)) # stored_energies', 'dissipated_energies', 'internal_state_variables # print(material.mat_data.s1.internal_state_variables) # --- VOLUMETRIC FORCES v = problem.finite_element.cell_basis_l.evaluate_function( _x_q_c, x_c, h_c) for load in problem.loads: vl = _w_q_c * v * load.function(time_step, _x_q_c) _re0 = load.direction * _cl _re1 = (load.direction + 1) * _cl element_external_forces[_re0:_re1] += vl # --- COMPUTE STIFFNESS MATRIX CONTRIBUTION AT QUADRATURE POINT element_stiffness_matrix += _w_q_c * ( element.gradients_operators[_qc].T @ material. mat_data.K[_qp] @ element.gradients_operators[_qc]) # --- COMPUTE STIFFNESS MATRIX CONTRIBUTION AT QUADRATURE POINT element_internal_forces += _w_q_c * ( element.gradients_operators[_qc].T @ material.mat_data.s1.thermodynamic_forces[_qp]) _qp += 1 _local_qp += 1 if verbose: print( "ELEM : {} | INTERNAL_FORCES_BEFORE STAB : \n {}". format(_element_index, element_internal_forces)) # --- STAB PARAMETER CHANGE stab_param = stab_coef * material.stabilization_parameter # if check and iteration > 0: # numerical_element_stiffness_matrix = ( # numerical_forces_bs_0[_element_index] - # numerical_forces_bs_1[_element_index] # ) / (2.0 * noise) # check_num = np.max( # np.abs(numerical_element_stiffness_matrix - element_stiffness_matrix) # ) / np.max(np.abs(element_stiffness_matrix)) # if check_num > noise_tolerance: # print( # "AT ELEM : {} | CHECK_BEFORE_STAB : {}".format(str(_element_index).zfill(6), check_num) # ) # --- ADDING STABILIZATION CONTRIBUTION AT THE ELEMENT LEVEL element_stiffness_matrix += stab_param * element.stabilization_operator # element_stiffness_matrix -= stab_param * element.stabilization_operator # --- ADDING STABILIZATION CONTRIBUTION AT THE ELEMENT LEVEL element_internal_forces += ( stab_param * element.stabilization_operator @ element. get_element_unknown_vector(faces_unknown_vector)) # --- MATRIX VECTOR DECOMPOSITION K_cc = element_stiffness_matrix[:_c0_c, :_c0_c] K_cf = element_stiffness_matrix[:_c0_c, _c0_c:] # local_external_forces_coefficient = np.max(np.abs(element_external_forces)) element_residual = element_internal_forces - element_external_forces # if local_external_forces_coefficient == 0.: # local_external_forces_coefficient = 1.0 # local_external_forces_coefficient = normalization_lagrange_coefficient # local_external_forces_coefficient = 1./element.cell.shape.volume R_cc = element_residual[:_c0_c] if iteration == 0: local_external_forces_coefficient = 1.0 cell_correction = np.ones((_cl * _dx, ), dtype=real) if _local_iteration == 0 and iteration > 0: cell_correction = np.ones((_cl * _dx, ), dtype=real) local_external_forces_coefficient = np.max( np.abs(R_cc)) # local_external_forces_coefficient = 1. # if local_external_forces_coefficient == 0.0 or local_external_forces_coefficient < local_tolerance: if local_external_forces_coefficient == 0.0: local_external_forces_coefficient = 1.0 # R_cell = R_cc - K_cf @ local_faces_correction # print("LOCAL_EXTERNAL_FORCES_COEF : {}".format(local_external_forces_coefficient)) R_cell = R_cc local_residual_evaluation = np.max( np.abs(R_cell) / local_external_forces_coefficient) # local_residual_evaluation = np.max(np.abs(cell_correction)) # if local_residual_evaluation > R_cell_value_previous: # print("!!!! RESIUDAL INCREASE :\n {}".format(element.cell.quadrature_points)) # R_cell_value_previous = local_residual_evaluation print("LOCAL ITER : {} | RES MAX : {}".format( _local_iteration, local_residual_evaluation)) if local_residual_evaluation < local_tolerance: break else: cell_correction = np.linalg.solve(-K_cc, R_cell) element.cell_unknown_vector += cell_correction if _local_iteration != number_of_local_iterations - 1: _qp -= _local_qp # element_internal_forces -= ( # stab_param # * element.stabilization_operator # @ element.get_element_unknown_vector(problem.field, problem.finite_element, faces_unknown_vector) # ) # -------------------------------------------------------------------------------------------------- # CONDENSATION # -------------------------------------------------------------------------------------------------- m_cell_cell = element_stiffness_matrix[:_c0_c, :_c0_c] m_cell_faces = element_stiffness_matrix[:_c0_c, _c0_c:] m_faces_cell = element_stiffness_matrix[_c0_c:, :_c0_c] m_faces_faces = element_stiffness_matrix[_c0_c:, _c0_c:] # v_cell = element_residual[:_c0_c] # v_faces = element_residual[_c0_c:] v_cell = -element_residual[:_c0_c] v_faces = -element_residual[_c0_c:] m_cell_cell_inv = np.linalg.inv(m_cell_cell) if debug_mode == 0: print("TANGENT MATRIX IN CONDENSATION COND :") print("{}".format(np.linalg.cond(m_cell_cell))) # ge = m_faces_cell @ m_cell_cell_inv # gd = (m_faces_cell @ m_cell_cell_inv) @ m_cell_faces K_cond = m_faces_faces - ( (m_faces_cell @ m_cell_cell_inv) @ m_cell_faces) R_cond = v_faces - (m_faces_cell @ m_cell_cell_inv) @ v_cell # --- SET CONDENSATION/DECONDENSATION MATRICES # element.m_cell_cell_inv = m_cell_cell_inv # element.m_cell_faces = m_cell_faces # element.v_cell = v_cell # --- ASSEMBLY for _i_local, _i_global in enumerate(element.faces_indices): _rg0 = _i_global * (_fk * _dx) _rg1 = (_i_global + 1) * (_fk * _dx) _re0 = _i_local * (_fk * _dx) _re1 = (_i_local + 1) * (_fk * _dx) residual[_rg0:_rg1] += R_cond[_re0:_re1] for _j_local, _j_global in enumerate( element.faces_indices): _cg0 = _j_global * (_fk * _dx) _cg1 = (_j_global + 1) * (_fk * _dx) _ce0 = _j_local * (_fk * _dx) _ce1 = (_j_local + 1) * (_fk * _dx) tangent_matrix[_rg0:_rg1, _cg0:_cg1] += K_cond[_re0:_re1, _ce0:_ce1] # --- SET EXTERNAL FORCES COEFFICIENT if np.max(np.abs(element_external_forces) ) > external_forces_coefficient: external_forces_coefficient = np.max( np.abs(element_external_forces)) # if check and iteration > 0: # numerical_element_stiffness_matrix = ( # numerical_forces_as_0[_element_index] - # numerical_forces_as_1[_element_index] # ) / (2.0 * noise) # check_num = np.max( # np.abs(numerical_element_stiffness_matrix - element_stiffness_matrix) # ) / np.max(np.abs(element_stiffness_matrix)) # if check_num > noise_tolerance: # print( # "AT ELEM : {} | CHECK_BEFORE_STAB : {}".format(str(_element_index).zfill(6), check_num) # ) if verbose: pass # print("ELEM : {} | INTERNAL_FORCES_AFTER STAB : \n {}".format(_element_index, # element_internal_forces)) # _iv0 = _element_index * len(element.cell.quadrature_weights) # _iv1 = (_element_index + 1) * len(element.cell.quadrature_weights) # print("ELEM : {} | DISPLACEMENT S0 : \n {}".format(_element_index, # element.get_element_unknown_vector(problem.field, # problem.finite_element, # faces_unknown_vector_previous_step))) # print("ELEM : {} | GRADIENTS S0 : \n {}".format(_element_index, # material.mat_data.s0.gradients[_iv0:_iv1])) # print("ELEM : {} | DISPLACEMENT S1 : \n {}".format(_element_index, # element.get_element_unknown_vector(problem.field, # problem.finite_element, # faces_unknown_vector))) # print("ELEM : {} | GRADIENTS S1 : \n {}".format(_element_index, # material.mat_data.s1.gradients[_iv0:_iv1])) # if not material.behaviour_name == "Elasticity": # print("ELEM : {} | INTERNAL_STATE_VARIABLES S0 : \n {}".format(_element_index, # material.mat_data.s0.internal_state_variables[ # _iv0:_iv1])) # print("ELEM : {} | INTERNAL_STATE_VARIABLES S1 : \n {}".format(_element_index, # material.mat_data.s1.internal_state_variables[ # _iv0:_iv1])) # --- BOUNDARY CONDITIONS for boundary_condition in problem.boundary_conditions: # --- DISPLACEMENT CONDITIONS if boundary_condition.boundary_type == BoundaryType.DISPLACEMENT: for f_local, f_global in enumerate( element.faces_indices): if (f_global in problem.mesh.faces_boundaries_connectivity[ boundary_condition.boundary_name]): _l0 = _system_size + iter_face_constraint * _fk _l1 = _system_size + (iter_face_constraint + 1) * _fk _c0 = _cl * _dx + ( f_local * _dx * _fk) + boundary_condition.direction * _fk _c1 = _cl * _dx + (f_local * _dx * _fk) + ( boundary_condition.direction + 1) * _fk _r0 = f_global * _fk * _dx + _fk * boundary_condition.direction _r1 = f_global * _fk * _dx + _fk * ( boundary_condition.direction + 1) # ------- # face_displacement = element_unknown_increment[_r0:_r1] # face_displacement = np.copy(element_unknown_increment[_c0:_c1]) # face_displacement = element_unknown_increment[_c0:_c1] face_lagrange = faces_unknown_vector[_l0:_l1] face_displacement = faces_unknown_vector[ _r0:_r1] _m_psi_psi_face = np.zeros((_fk, _fk), dtype=real) _v_face_imposed_displacement = np.zeros( (_fk, ), dtype=real) face = element.faces[f_local] x_f = face.get_centroid() h_f = face.get_diameter() face_rot = face.get_rotation_matrix() face_quadrature_size = face.get_quadrature_size( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_points = face.get_quadrature_points( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_weights = face.get_quadrature_weights( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) for _qf in range(face_quadrature_size): _x_q_f = face_quadrature_points[:, _qf] _w_q_f = face_quadrature_weights[_qf] _s_q_f = (face_rot @ _x_q_f)[:-1] _s_f = (face_rot @ x_f)[:-1] v = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) _v_face_imposed_displacement += ( _w_q_f * v * boundary_condition.function( time_step, _x_q_f)) _psi_k = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) _m_psi_psi_face += _w_q_f * np.tensordot( _psi_k, _psi_k, axes=0) _m_psi_psi_face_inv = np.linalg.inv( _m_psi_psi_face) if debug_mode == 0: print( "FACE MASS MATRIX IN DIRICHLET BOUND COND :" ) print("{}".format( np.linalg.cond(_m_psi_psi_face))) imposed_face_displacement = _m_psi_psi_face_inv @ _v_face_imposed_displacement face_displacement_difference = face_displacement - imposed_face_displacement # --- LAGRANGE INTERNAL FORCES PART # element_internal_forces[_c0:_c1] += ( # normalization_lagrange_coefficient * face_lagrange # ) # residual[_r0:_r1] += ( # normalization_lagrange_coefficient * face_lagrange # ) residual[_r0:_r1] -= ( normalization_lagrange_coefficient * face_lagrange) # --- LAGRANGE MULTIPLIERS PART # residual[_l0:_l1] += ( # normalization_lagrange_coefficient * face_displacement_difference # ) residual[_l0:_l1] -= ( normalization_lagrange_coefficient * face_displacement_difference) # --- LAGRANGE MATRIX PART tangent_matrix[ _l0:_l1, _r0: _r1] += normalization_lagrange_coefficient * np.eye( _fk, dtype=real) tangent_matrix[ _r0:_r1, _l0: _l1] += normalization_lagrange_coefficient * np.eye( _fk, dtype=real) # --- SET EXTERNAL FORCES COEFFICIENT lagrange_external_forces = ( normalization_lagrange_coefficient * imposed_face_displacement) if np.max(np.abs(lagrange_external_forces) ) > external_forces_coefficient: external_forces_coefficient = np.max( np.abs(lagrange_external_forces)) iter_face_constraint += 1 elif boundary_condition.boundary_type == BoundaryType.PRESSURE: for f_local, f_global in enumerate( element.faces_indices): if (f_global in problem.mesh.faces_boundaries_connectivity[ boundary_condition.boundary_name]): face = element.faces[f_local] x_f = face.get_centroid() h_f = face.get_diameter() face_rot = face.get_rotation_matrix() face_quadrature_size = face.get_quadrature_size( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_points = face.get_quadrature_points( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) face_quadrature_weights = face.get_quadrature_weights( problem.finite_element. construction_integration_order, quadrature_type=problem.quadrature_type, ) for _qf in range(face_quadrature_size): # _h_f = element.faces[f_local].shape.diameter # _x_f = element.faces[f_local].shape.centroid _x_q_f = face_quadrature_points[:, _qf] _w_q_f = face_quadrature_weights[_qf] _s_q_f = (face_rot @ _x_q_f)[:-1] _s_f = (face_rot @ x_f)[:-1] v = problem.finite_element.face_basis_k.evaluate_function( _s_q_f, _s_f, h_f) vf = _w_q_f * v * boundary_condition.function( time_step, _x_q_f) # _c0 = _dx * _cl + f_local * _dx * _fk + boundary_condition.direction * _fk # _c1 = _dx * _cl + f_local * _dx * _fk + (boundary_condition.direction + 1) * _fk _r0 = f_global * _fk * _dx + _fk * boundary_condition.direction _r1 = f_global * _fk * _dx + _fk * ( boundary_condition.direction + 1) # element_external_forces[_c0:_c1] += vf # residual[_r0:_r1] -= vf residual[_r0:_r1] += vf if np.max(np.abs( vf)) > external_forces_coefficient: external_forces_coefficient = np.max( np.abs(vf)) # -------------------------------------------------------------------------------------------------- # RESIDUAL EVALUATION # -------------------------------------------------------------------------------------------------- if external_forces_coefficient == 0.0: external_forces_coefficient = 1.0 residual_evaluation = np.max( np.abs(residual)) / external_forces_coefficient print("ITER : {} | RES_MAX : {}".format( str(iteration).zfill(4), residual_evaluation)) # print("ITER : {} | =====================================================================".format(str(iteration).zfill(4))) # residual_values.append(residual_evaluation) # if residual_evaluation < problem.tolerance: if residual_evaluation < problem.tolerance or iteration == problem.number_of_iterations - 1: # ---------------------------------------------------------------------------------------------- # UPDATE INTERNAL VARIABLES # ---------------------------------------------------------------------------------------------- mgis_bv.update(material.mat_data) print("ITERATIONS : {}".format(iteration + 1)) problem.write_vertex_res_files(problem.res_folder_path, file_suffix, faces_unknown_vector) problem.write_quadrature_points_res_files( problem.res_folder_path, file_suffix, material, faces_unknown_vector) faces_unknown_vector_previous_step += faces_unknown_vector residual_values.append(residual_evaluation) break else: # ---------------------------------------------------------------------------------------------- # SOLVE SYSTEM # ---------------------------------------------------------------------------------------------- if debug_mode == 0: print("K GLOBAL COND") print("{}".format(np.linalg.cond(tangent_matrix))) # sparse_global_matrix = csr_matrix(-tangent_matrix) sparse_global_matrix = csr_matrix(tangent_matrix) correction = spsolve(sparse_global_matrix, residual) print("CORRECTION :") # print(correction) # correction = np.linalg.solve(-tangent_matrix, residual) faces_unknown_vector += correction if verbose: print( "R_K_RES : \n {}".format(residual - tangent_matrix @ correction)) print("R_K_RES_NORMALIZED : \n {}".format( (residual - tangent_matrix @ correction) / external_forces_coefficient)) plt.plot(range(len(residual_values)), residual_values, label="residual") plt.plot(range(len(residual_values)), [problem.tolerance for local_i in range(len(residual_values))], label="tolerance") plt.ylabel("resiudal after convergence") plt.xlabel("time step index") plt.title("evolution of the residual") plt.legend() plt.gcf().subplots_adjust(left=0.15) plt.show() return
def test_cook_finite_strain_voce_isotropic_hardening(self): # --- VALUES time_steps = np.linspace(0.0, 7.0e-3, 50) time_steps = np.linspace(0.0, 14.e-3, 150) P_min = 0.0 P_max = 5.e6 / (16.e-3) # P_max = 3.e8 # P_min = 0.01 # P_max = 1. / 16. # time_steps = np.linspace(P_min, P_max, 20)[:-3] time_steps = np.linspace(P_min, P_max, 10) time_steps = list(time_steps) + [P_max] print(time_steps) iterations = 10 # --- LOAD def volumetric_load(time: float, position: ndarray): return 0 loads = [Load(volumetric_load, 0), Load(volumetric_load, 1)] # --- BC def pull(time: float, position: ndarray) -> float: return time def fixed(time: float, position: ndarray) -> float: return 0.0 boundary_conditions = [ BoundaryCondition("RIGHT", pull, BoundaryType.PRESSURE, 1), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 1), BoundaryCondition("LEFT", fixed, BoundaryType.DISPLACEMENT, 0), ] # --- MESH mesh_file_path = "meshes/cook_5.geof" # mesh_file_path = "meshes/cook_30.geof" # mesh_file_path = "meshes/cook_quadrangles_1.msh" # mesh_file_path = "meshes/cook_quadrangles_0.msh" # mesh_file_path = "meshes/cook_20_quadrangles_structured.msh" # mesh_file_path = "meshes/cook_01_quadrangles_structured.msh" # mesh_file_path = "meshes/cook_10_triangles_structured.msh" mesh_file_path = "meshes/cook_16_triangles_structured.msh" # --- FIELD displacement = Field( label="U", field_type=FieldType.DISPLACEMENT_LARGE_STRAIN_PLANE_STRAIN) # --- FINITE ELEMENT finite_element = FiniteElement( element_type=ElementType.HDG_EQUAL, polynomial_order=1, euclidean_dimension=displacement.euclidean_dimension, basis_type=BasisType.MONOMIAL, ) # --- PROBLEM p = Problem(mesh_file_path=mesh_file_path, field=displacement, finite_element=finite_element, time_steps=time_steps, iterations=iterations, boundary_conditions=boundary_conditions, loads=loads, quadrature_type=QuadratureType.GAUSS, tolerance=1.0e-6, res_folder_path=get_current_res_folder_path()) # --- MATERIAL parameters = { "YoungModulus": 206.e9, "PoissonRatio": 0.29, "HardeningSlope": 10.0e9, "YieldStress": 300.0e6 } # stabilization_parameter = 1000. * parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) stabilization_parameter = 0.00005 * parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) stabilization_parameter = 0.001 * parameters["YoungModulus"] / ( 1.0 + parameters["PoissonRatio"]) # stabilization_parameter = 0.0000 * parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) # stabilization_parameter = 1.0 * parameters["YoungModulus"] / (1.0 + parameters["PoissonRatio"]) mat = Material( nq=p.mesh.number_of_cell_quadrature_points_in_mesh, library_path="behaviour/src/libBehaviour.so", library_name="Voce", hypothesis=mgis_bv.Hypothesis.PLANESTRAIN, stabilization_parameter=stabilization_parameter, lagrange_parameter=parameters["YoungModulus"], field=displacement, parameters=None, ) # --- SOLVE solve_newton_2(p, mat, verbose=False, debug_mode=DebugMode.NONE) # solve_newton_exact(p, mat, verbose=False, debug_mode=DebugMode.NONE) from pp.plot_ssna import plot_det_f # plot_det_f(46, "res") res_folder = "res" # res_folder = "/home/dsiedel/projetcs/h2o/tests/test_mechanics/test_cook_finite_strain_isotropic_voce_hardening/res_cook_20_ord1_quad/res" from os import walk, path import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap def __plot(column: int, time_step_index: int): _, _, filenames = next(walk(res_folder)) # for time_step_index in range(1, len(time_steps)): # for time_step_index in range(30, len(time_steps)): for filename in filenames: if "{}".format(time_step_index).zfill( 6) in filename and "qdp" in filename: hho_file_path = path.join(res_folder, filename) with open(hho_file_path, "r") as hho_res_file: fig, ax0d = plt.subplots(nrows=1, ncols=1) c_hho = hho_res_file.readlines() field_label = c_hho[0].split(",")[column] number_of_points = len(c_hho) - 1 # for _iloc in range(len(c_hho)): # line = c_hho[_iloc] # x_coordinates = float(line.split(",")[0]) # y_coordinates = float(line.split(",")[1]) # if (x_coordinates - 0.0) ** 2 + (y_coordinates) eucli_d = displacement.euclidean_dimension points = np.zeros((eucli_d, number_of_points), dtype=real) field_vals = np.zeros((number_of_points, ), dtype=real) field_min_val = np.inf field_max_val = -np.inf for l_count, line in enumerate(c_hho[1:]): x_coordinates = float(line.split(",")[0]) y_coordinates = float(line.split(",")[1]) field_value = float(line.split(",")[column]) points[0, l_count] += x_coordinates points[1, l_count] += y_coordinates field_vals[l_count] += field_value # if field_vals[l_count] x, y = points colors = [(0, 0, 1), (0, 1, 1), (0, 1, 0), (1, 1, 0), (1, 0, 0)] # perso = LinearSegmentedColormap.from_list("perso", colors, N=1000) perso = LinearSegmentedColormap.from_list("perso", colors, N=20) vmin = min(field_vals[:]) vmax = max(field_vals[:]) # vmin = 300.e6 # vmax = 400.e6 # vmin = 8.e8/3. # vmax = 12.e8/3. # levels = np.linspace(vmin, vmax, 50, endpoint=True) levels = np.linspace(vmin, vmax, 20, endpoint=True) ticks = np.linspace(vmin, vmax, 10, endpoint=True) datad = ax0d.tricontourf(x, y, field_vals[:], cmap=perso, levels=levels) ax0d.get_xaxis().set_visible(False) ax0d.get_yaxis().set_visible(False) ax0d.set_xlabel("map of the domain $\Omega$") cbar = fig.colorbar(datad, ax=ax0d, ticks=ticks) cbar.set_label("{} : {}".format( field_label, time_step_index), rotation=270, labelpad=15.0) # plt.savefig("/home/dsiedel/Projects/pythhon/plots/{}.png".format(time_step)) plt.show() for tsindex in [1, 50, 100, 192]: # __plot(15, tsindex) pass # __plot(15, 19) __plot(15, 34)