Exemplo n.º 1
0
 def test_behaviour_data(self):
     pr = -1.2e5
     eps = -pr * 1.e-14
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     d = mgis_bv.BehaviourData(b)
     mgis_bv.setExternalStateVariable(d.s0, "Temperature", 293.15)
     mgis_bv.setExternalStateVariable(d.s1, "Temperature", 293.15)
     inputs = numpy.asarray([pr], dtype=numpy.float64)
     v = mgis_bv.make_view(d)
     mgis_bv.executeInitializeFunction(v, b, "StressFromInitialPressure",
                                       inputs)
     # Due to restrictions of the BehaviourDataView class (the
     # initial state is assumed immutable), only the state at the
     # end of the time step is initialized. Calling update is thus
     # required in most cases
     mgis_bv.update(d)
     s0 = d.s0.thermodynamic_forces
     s1 = d.s1.thermodynamic_forces
     for i in range(0, 3):
         self.assertTrue(
             abs(s0[i] - pr) < eps,
             "invalid stress value at the beginning of the time step")
         self.assertTrue(
             abs(s1[i] - pr) < eps,
             "invalid stress value at the end of the time step")
     for i in range(3, 6):
         self.assertTrue(
             abs(s0[i]) < eps,
             "invalid stress value at the beginning of the time step")
         self.assertTrue(
             abs(s1[i]) < eps,
             "invalid stress value at the end of the time step")
Exemplo n.º 2
0
 def test_behaviour_data2(self):
     E = 200e9
     nu = 0.3
     sxx = 150e6
     eps = 10 * sxx * 1e-14
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     d = mgis_bv.BehaviourData(b)
     d.s0.thermodynamic_forces[:] = [sxx, 0, 0, 0, 0, 0]
     mgis_bv.setExternalStateVariable(d.s0, "Temperature", 293.15)
     mgis_bv.setExternalStateVariable(d.s1, "Temperature", 293.15)
     v = mgis_bv.make_view(d)
     mgis_bv.executeInitializeFunction(v, b,
                                       "ElasticStrainFromInitialStress")
     # Due to restrictions of the BehaviourDataView class (the
     # initial state is assumed immutable), only the state at the
     # end of the time step is initialized. Calling update is thus
     # required in most cases
     mgis_bv.update(d)
     eel_values = [sxx / E, -nu * sxx / E, -nu * sxx / E, 0, 0, 0]
     eel0 = d.s0.internal_state_variables
     eel1 = d.s1.internal_state_variables
     for i in range(0, 6):
         self.assertTrue(
             abs(eel0[i] - eel_values[i]) < eps,
             "invalid elastic strain value at the beginning of the time step"
         )
         self.assertTrue(
             abs(eel1[i] - eel_values[i]) < eps,
             "invalid elastic strain value at the end of the time step")
Exemplo n.º 3
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)
Exemplo n.º 4
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
 def test_behaviour_data(self):
     eps = 1.e-14
     e = numpy.asarray([1.3e-2, 1.2e-2, 1.4e-2, 0., 0., 0.],
                       dtype=numpy.float64)
     e2 = numpy.asarray([1.2e-2, 1.3e-2, 1.4e-2, 0., 0., 0.],
                        dtype=numpy.float64)
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     m = mgis_bv.MaterialDataManager(b, 2)
     mgis_bv.setMaterialProperty(m.s1, "YoungModulus", 150e9)
     mgis_bv.setMaterialProperty(m.s1, "PoissonRatio", 0.3)
     mgis_bv.setExternalStateVariable(m.s1, "Temperature", 293.15)
     mgis_bv.update(m)
     m.s1.gradients[0:] = e
     m.s1.gradients[1:] = e
     outputs = numpy.empty(shape=(2, 3), dtype=numpy.float64)
     mgis_bv.executePostProcessing(outputs.reshape(6), m, "PrincipalStrain")
     for i in range(0, 3):
         self.assertTrue(
             abs(outputs[0, i] - e2[i]) < eps, "invalid output value")
         self.assertTrue(
             abs(outputs[1, i] - e2[i]) < eps, "invalid output value")
Exemplo n.º 7
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
Exemplo n.º 8
0
 def test_data_manager2(self):
     """
     Call an initialize function with non uniform inputs
     """
     pr = [-1.2e5, 0.7e5]
     eps = -pr[0] * 1.e-14
     h = mgis_bv.Hypothesis.Tridimensional
     b = self.__get_behaviour(h)
     d = mgis_bv.MaterialDataManager(b, 2)
     mgis_bv.setExternalStateVariable(d.s0, "Temperature", 293.15)
     mgis_bv.setExternalStateVariable(d.s1, "Temperature", 293.15)
     inputs = numpy.asarray(pr, dtype=numpy.float64)
     mgis_bv.executeInitializeFunction(d, "StressFromInitialPressure",
                                       inputs)
     # Due to restrictions of the BehaviourDataView class (the
     # initial state is assumed immutable), only the state at the
     # end of the time step is initialized. Calling update is thus
     # required in most cases
     mgis_bv.update(d)
     s0 = d.s0.thermodynamic_forces
     s1 = d.s1.thermodynamic_forces
     for n in range(0, 2):
         for i in range(0, 3):
             self.assertTrue(
                 abs(s0[n][i] - pr[n]) < eps,
                 "invalid stress value at the beginning of the time step")
             self.assertTrue(
                 abs(s1[n][i] - pr[n]) < eps,
                 "invalid stress value at the end of the time step")
         for i in range(3, 6):
             self.assertTrue(
                 abs(s0[n][i]) < eps,
                 "invalid stress value at the beginning of the time step")
             self.assertTrue(
                 abs(s1[n][i]) < eps,
                 "invalid stress value at the end of the time step")
Exemplo n.º 9
0
 def f(self, x):
     """Objective function"""
     self.u.vector()[:] = x
     self.update_constitutive_law()
     mgis_bv.update(self.material.data_manager)
     return self.get_total_energy()
Exemplo n.º 10
0
 def solve(self, x):
     if self._init:
         self.initialize()
     solv_out = self.solver.solve(self, x)
     mgis_bv.update(self.material.data_manager)
     return solv_out
    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
Exemplo n.º 12
0
        Dt.vector().apply("insert")
        print("Coupled Tangent Operator:", tangent_operators[1::2])
        # retrieve cumulated plastic strain values
        p.vector().set_local(m.s1.internal_state_variables[:, -1])
        p.vector().apply("insert")
        # solve Newton system
        A, Res = assemble_system(a_Newton, res, bc)
        nRes = Res.norm("l2")
        print("    Residual at the end:", nRes)
        niter += 1
    # update the displacement for the next increment
    vt.assign(vt1)
    (u, theta) = vt.split()
    # update the material
    # the update function updates an instance of the MaterialStateManager by copying the state s1 at the end of the time step in the state s0 at the beginning of the time step.
    mgis_bv.update(m)
    # postprocessing results
    file_results.write(u, t)
    p_avg.assign(project(p, P0))
    file_results.write(p_avg, t)
    results[i+1, :] = (u(0, 0, 0)[0], t)

import matplotlib.pyplot as plt
plt.plot(results[:, 0], results[:, 1], "-o")
plt.xlabel("Displacement of inner boundary")
plt.ylabel(r"Applied pressure $q/q_{lim}$")
plt.show()

# .. note::
#  Note that we defined the cumulative plastic strain variable :math:`p` in FEniCS
#  only for post-processing purposes. In fact, FEniCS deals only with the global equilibrium
Exemplo n.º 13
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
Exemplo n.º 14
0
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
Exemplo n.º 15
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)