示例#1
0
 def __updateStrainStress(self, du):  # private method (self-explanatory)
     """
     :var du: nodal displacement increment
     """
     dstrain = self.__spfem.calcStrain(VectorX(du))
     self.__materData.s1.gradients[:, :] += numpy.array(dstrain)
     mgis_bv.integrate(self.__materData, intType, self.__dt, 0,
                       self.__materData.n)
     mgis_bv.update(self.__materData)
示例#2
0
 def __updateMaterialData(self,res):
     self.__materData = mgis_bv.MaterialDataManager(behaviour, self.__npts)
     for s in [self.__materData.s0, self.__materData.s1]: # material initialization
         mgis_bv.setMaterialProperty(s,"YoungModulus",self.mater['young'])
         mgis_bv.setMaterialProperty(s,"PoissonRatio",self.mater['poisson'])
         mgis_bv.setMaterialProperty(s,"InitYieldStress",self.mater['tau0'])
         mgis_bv.setMaterialProperty(s,"ResidualYieldStress",self.mater['taur'])
         mgis_bv.setMaterialProperty(s,"SoftenExponent",self.mater['b'])
         mgis_bv.setExternalStateVariable(s,"Temperature",293.15)
         s.internal_state_variables[:,:] = res[:,:5]
         #s.thermodynamic_forces[:,:] = res[:,5:9]
         s.gradients[:,:] = res[:,5:]
     mgis_bv.integrate(pool, self.__materData, intType, self.__dt)
     mgis_bv.update(self.__materData)
    def test_pass(self):

        # path to the test library
        lib = os.environ['MGIS_TEST_BEHAVIOURS_LIBRARY']
        # reference values
        pref = [
            0, 1.3523277308229e-11, 1.0955374667213e-07, 5.5890770166084e-06,
            3.2392193670428e-05, 6.645865307584e-05, 9.9676622883138e-05,
            0.00013302758358953, 0.00016635821069889, 0.00019969195920296,
            0.00023302522883648, 0.00026635857194317, 0.000299691903777,
            0.0003330252373404, 0.00036635857063843, 0.00039969190397718,
            0.00043302523730968, 0.00046635857064314, 0.00049969190397646,
            0.00053302523730979, 0.00056635857064313
        ]
        # comparison criterion
        eps = 1.e-12

        b = mgis_bv.load(lib, 'Norton', mgis_bv.Hypothesis.Tridimensional)
        d = mgis_bv.BehaviourData(b)
        o = mgis_bv.getVariableOffset(b.isvs, 'EquivalentViscoplasticStrain',
                                      b.hypothesis)

        # strain increment per time step
        de = 5.e-5
        # time step
        d.dt = 180

        # setting the temperature
        mgis_bv.setExternalStateVariable(d.s1, 'Temperature', 293.15)

        # copy d.s1 in d.s0
        mgis_bv.update(d)
        d.s1.gradients[0] = de

        # equivalent plastic strain
        p = [d.s0.internal_state_variables[o]]

        # integrate the behaviour
        for i in range(0, 20):
            mgis_bv.integrate(d, b)
            mgis_bv.update(d)
            d.s1.gradients[0] += de
            p.append(d.s1.internal_state_variables[o])

        # check-in results
        for i in range(0, 20):
            self.assertTrue(abs(p[i] - pref[i]) < eps)

        pass
示例#4
0
 def update_constitutive_law(self):
     """Performs the consitutive law update"""
     for c in self._before_update_constitutive_law_callbacks:
         c()
     self.update_gradients()
     self.material.update_external_state_variables(
         self.quadrature_degree, self.mesh,
         self.state_variables["external"])
     # integrate the behaviour
     mgis_bv.integrate(
         self.material.data_manager,
         self.integration_type,
         self.dt,
         0,
         self.material.data_manager.n,
     )
     # getting the stress and consistent tangent operator back to
     # the FEniCS world.
     self.update_fluxes()
     self.update_tangent_blocks()
     self.update_internal_state_variables()
 def test_behaviour_data(self):
     eps = 1.e-14
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     d = mgis_bv.BehaviourData(b)
     self.assertTrue(len(d.s0.external_state_variables) == 55,
                     "invalid array size for the external state variables")
     self.assertTrue(len(d.s1.external_state_variables) == 55,
                     "invalid array size for the external state variables")
     v_esv_values = numpy.asarray([1, 2, 3], dtype=numpy.float64)
     print(v_esv_values)
     mgis_bv.setExternalStateVariable(d.s1, "v_esv", v_esv_values)
     mgis_bv.integrate(d, b)
     for i in range(0, 3):
         self.assertTrue(abs(d.s1.external_state_variables[i + 1] -
                             v_esv_values[i]) < eps,
                         "invalid external state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[i] -
                             v_esv_values[i]) <  eps,
                         "invalid internal state variable value")
     pass
示例#6
0
    def test_pass(self):

        # path to the test library
        lib = os.environ['MGIS_TEST_MODELS_LIBRARY']
        # modelling hypothesis
        h = mgis_bv.Hypothesis.Tridimensional
        # loading the behaviour
        model = mgis.model.load(lib, 'ode_rk54', h)
        # default value of parameter A
        A = model.getParameterDefaultValue('A')
        # material data manager
        d = mgis_bv.BehaviourData(model)
        # index of x in the array of state variable
        o = mgis_bv.getVariableOffset(model.isvs, 'x', h)
        # time step increment
        d.dt = 0.1
        # type of storage
        mgis_bv.setExternalStateVariable(d.s1, 'Temperature', 293.15)
        # Initial value of x
        d.s1.internal_state_variables[o] = 1
        # copy d.s1 in d.s0
        mgis_bv.update(d)
        # values of  x
        xvalues = [d.s0.internal_state_variables[o]]
        # integration
        for i in range(0, 10):
            mgis_bv.integrate(d, model)
            mgis_bv.update(d)
            xvalues.append(d.s1.internal_state_variables[o])
        # checks
        # comparison criterion
        eps = 1.e-10
        t = 0
        for i in range(0, 11):
            x_ref = math.exp(-A * t)
            self.assertTrue(abs(xvalues[i] - x_ref) < eps)
            t = t + d.dt

        pass
    def test_pass(self):

        print(dir(mgis))
        # path to the test library
        lib = os.environ['MGIS_TEST_BEHAVIOURS_LIBRARY']
        # reference values
        pref = [
            0, 1.3523277308229e-11, 1.0955374667213e-07, 5.5890770166084e-06,
            3.2392193670428e-05, 6.645865307584e-05, 9.9676622883138e-05,
            0.00013302758358953, 0.00016635821069889, 0.00019969195920296,
            0.00023302522883648, 0.00026635857194317, 0.000299691903777,
            0.0003330252373404, 0.00036635857063843, 0.00039969190397718,
            0.00043302523730968, 0.00046635857064314, 0.00049969190397646,
            0.00053302523730979, 0.00056635857064313
        ]
        # modelling hypothesis
        h = mgis_bv.Hypothesis.Tridimensional
        # loading the behaviour
        b = mgis_bv.load(lib, 'Norton', h)
        # number of integration points
        nig = 100
        # material data manager
        m = mgis_bv.MaterialDataManager(b, nig)
        # index of the equivalent viscplastic strain in the array of
        # state variable
        o = mgis_bv.getVariableOffset(b.isvs, 'EquivalentViscoplasticStrain',
                                      h)
        # strain increment per time step
        de = 5.e-5
        # time step increment
        dt = 180
        # setting the temperature
        mgis_bv.setExternalStateVariable(m.s1, 'Temperature', 293.15)
        # copy d.s1 in d.s0
        mgis_bv.update(m)
        # index of the first integration point
        ni = 0
        # index of the last integration point
        ne = nig - 1
        # values of the equivalent plastic strain
        # for the first integration point
        pi = [m.s0.internal_state_variables[ni][o]]
        # values of the equivalent plastic strain
        # for the last integration point
        pe = [m.s0.internal_state_variables[ne][o]]
        # setting the gradient at the end of the first time step
        for i in range(0, nig):
            m.s1.gradients[i][0] = de
        # creating a thread pool for parallel integration
        p = mgis.ThreadPool(2)
        # integration
        for i in range(0, 20):
            it = mgis_bv.IntegrationType.IntegrationWithoutTangentOperator
            mgis_bv.integrate(p, m, it, dt)
            mgis_bv.update(m)
            for j in range(0, nig):
                m.s1.gradients[j][0] += de
            pi.append(m.s0.internal_state_variables[ni][o])
            pe.append(m.s0.internal_state_variables[ne][o])
        # checks
        # comparison criterion
        eps = 1.e-12
        for i in range(0, 21):
            self.assertTrue(abs(pi[i] - pref[i]) < eps)
            self.assertTrue(abs(pe[i] - pref[i]) < eps)

        pass
示例#8
0
# FunctionSpace (here piecewise constant) and Function for output of the equivalent
# plastic strain since XDMF output does not handle Quadrature elements::

file_results = XDMFFile("plasticity_results.xdmf")
file_results.parameters["flush_output"] = True
file_results.parameters["functions_share_mesh"] = True
P0 = FunctionSpace(mesh, "DG", 0)
p_avg = Function(P0, name="Plastic strain")

# The tangent stiffness is also initialized with the elasticity matrix:

# one integrates the behaviour over the time step and computes an elastic stiffness
it = mgis_bv.IntegrationType.PredictionWithElasticOperator
#print("m.n: ", m.n)
#m.n numer of intergation points
mgis_bv.integrate(m, it, 0, 0, m.n);
tangent_operators = m.K.flatten()
#print("m.K_stride:",m.K_stride)
Ct.vector().set_local(tangent_operators[0::2])
Ct.vector().apply("insert")
print("Tangent Operator:",tangent_operators[0::2])
# getting the coupled tangent operator
Dt.vector().set_local(tangent_operators[1::2])
Dt.vector().apply("insert")
print("Coupled Tangent Operator:",tangent_operators[1::2])


# The main difference with respect to the pure FEniCS implementation of the previous
# tutorial is that `MFront` computes the current stress state and stiffness matrix
# (``integrate`` method) based on the value of the total strain which is computed 
# from the total displacement estimate ``u1``. The associated strain is projected 
 def test_material_data_manager(self):
     eps = 1.e-14
     dt = 0.1
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     d = mgis_bv.MaterialDataManager(b, 2)
     mgis_bv.setMaterialProperty(d.s0, "YoungModulus", 150e9)
     mgis_bv.setMaterialProperty(d.s0, "PoissonRatio", 0.3)
     mgis_bv.setMaterialProperty(d.s1, "YoungModulus", 150e9)
     mgis_bv.setMaterialProperty(d.s1, "PoissonRatio", 0.3)
     # 
     zeros = numpy.zeros(9)
     # v_esv is uniform
     v_esv_values = numpy.asarray([1, 2, 3], dtype=numpy.float64)
     mgis_bv.setExternalStateVariable(d.s0, "v_esv", zeros[0:3],
                                      mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     mgis_bv.setExternalStateVariable(d.s1, "v_esv", v_esv_values,
                                      mgis_bv.MaterialStateManagerStorageMode.LOCAL_STORAGE)
     # v2_esv[0] is not uniform
     v2_esv0_values = numpy.asarray([1, 2, 3, 7, 6, 5], dtype=numpy.float64)
     mgis_bv.setExternalStateVariable(d.s0, "v2_esv[0]",zeros[0:3],
                                      mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     mgis_bv.setExternalStateVariable(d.s1, "v2_esv[0]", v2_esv0_values,
                                      mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     v2_esv1_values =  numpy.asarray([9, 8, 2, 3, 6, 4], dtype=numpy.float64)
     mgis_bv.setExternalStateVariable(d.s0, "v2_esv[1]", zeros[0:3],
                                      mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     mgis_bv.setExternalStateVariable(d.s1, "v2_esv[1]", v2_esv1_values,
                                      mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     for s in [d.s0, d.s1]:
         mgis_bv.setExternalStateVariable(s, "Temperature", zeros[0:1],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "s_esv", zeros[0:6],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "s2_esv[0]", zeros[0:6],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "s2_esv[1]", zeros[0:6],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "t_esv", zeros[0:9],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "t2_esv[0]", zeros[0:9],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
         mgis_bv.setExternalStateVariable(s, "t2_esv[1]", zeros[0:9],
                                          mgis_bv.MaterialStateManagerStorageMode.EXTERNAL_STORAGE)
     # checking if the external storage do work as expected
     v2_esv1_values[3] = -1
     mgis_bv.integrate(d, mgis_bv.IntegrationType.INTEGRATION_NO_TANGENT_OPERATOR, dt, 0, 2)
     for i in range (0, 3):
         self.assertTrue(abs(d.s1.internal_state_variables[0, i] - v_esv_values[i]) < eps,
                         "invalid internal state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[1, i] - v_esv_values[i]) < eps,
                         "invalid internal state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[0, i + 3] -
                             v2_esv0_values[i]) < eps,
                         "invalid internal state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[1, i + 3] -
                             v2_esv0_values[i + 3]) < eps,
                         "invalid internal state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[0, i + 6] -
                             v2_esv1_values[i]) < eps,
                          "invalid internal state variable value")
         self.assertTrue(abs(d.s1.internal_state_variables[1, i + 6] -
                             v2_esv1_values[i + 3]) < eps,
                         "invalid internal state variable value")
示例#10
0
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
示例#11
0
文件: exact.py 项目: davidsiedel/h2o
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
示例#12
0
 def __updateStrainStress(self,du): #private method
     dstrain = self.__spfem.calcStrain(VectorX(du))
     self.__materData.s1.gradients[:,:] += numpy.array(dstrain)
     mgis_bv.integrate(pool, self.__materData, IT, self.__dt) #parallel stress integration
     mgis_bv.update(self.__materData)