// Stiffness and RHS assembly // Equation references are from Samanta and Zabaras, 2005 void EnergySystem :: assemble(){ // GENERAL VARIABLES // Get a constant reference to the mesh object. const MeshBase& mesh = this->get_mesh(); // The dimension that we are running const unsigned int dim = this->ndim(); // FEM THERMODYNAMIC RELATIONSHIPS (ThermoEq Class) // Determine the FEM type (should be same for all ThermoEq variables) FEType fe_type_thermo = thermo->variable_type(0); // Build FE object; accessed via a pointer AutoPtr<FEBase> fe_thermo(FEBase::build(dim, fe_type_thermo)); // Setup a quadrature rule QGauss qrule_thermo(dim, fe_type_thermo.default_quadrature_order()); // Link FE and Quadrature fe_thermo->attach_quadrature_rule(&qrule_thermo); // References to shape functions and derivatives const vector<std::vector<Real> >& N_thermo = fe_thermo->get_phi(); const vector<std::vector<RealGradient> >& B_thermo = fe_thermo->get_dphi(); // Setup a DOF map const DofMap& dof_map_thermo = thermo->get_dof_map(); // FEM MOMENTUM EQUATION // Determine the FEM type FEType fe_type_momentum = momentum->variable_type(0); // Build FE object; accessed via a pointer AutoPtr<FEBase> fe_momentum(FEBase::build(dim, fe_type_momentum)); // Setup a quadrature rule QGauss qrule_momentum(dim, fe_type_momentum.default_quadrature_order()); // Link FE and Quadrature fe_momentum->attach_quadrature_rule(&qrule_momentum); // References to shape functions and derivatives const vector<std::vector<Real> >& N_momentum = fe_momentum->get_phi(); // Setup a DOF map const DofMap& dof_map_momentum = momentum->get_dof_map(); // FEM ENERGY EQ. RELATIONSHIPS // Get a constant reference to the Finite Element type // for the first (and only) variable in the system. FEType fe_type = this->variable_type(0); // Build a Finite Element object of the specified type AutoPtr<FEBase> fe (FEBase::build(dim, fe_type)); AutoPtr<FEBase> fe_face (FEBase::build(dim, fe_type)); // A Gauss quadrature rule for numerical integration. // Let the \p FEType object decide what order rule is appropriate. QGauss qrule (dim, fe_type.default_quadrature_order()); QGauss qface (dim-1, fe_type.default_quadrature_order()); // Tell the finite element object to use our quadrature rule. fe->attach_quadrature_rule(&qrule); fe_face->attach_quadrature_rule(&qface); // Here we define some references to cell-specific data that // will be used to assemble the linear system. We will start // with the element Jacobian * quadrature weight at each integration point. const vector<Real>& JxW = fe->get_JxW(); const vector<Real>& JxW_face = fe_face->get_JxW(); // The element shape functions evaluated at the quadrature points. const vector<std::vector<Real> >& N = fe->get_phi(); const vector<std::vector<Real> >& N_face = fe_face->get_phi(); // Element shape function gradients evaluated at quadrature points const vector<std::vector<RealGradient> >& B = fe->get_dphi(); // The XY locations of the quadrature points used for face integration const vector<Point>& qface_points = fe_face->get_xyz(); // A reference to the \p DofMap objects const DofMap& dof_map = this->get_dof_map(); // this system // DEFINE VECTOR AND MATRIX VARIABLES // Define data structures to contain the element matrix // and right-hand-side vector contribution (Eq. 107) DenseMatrix<Number> Me; // [\hat{M} + \hat{M}_{\delta}] DenseMatrix<Number> Ne; // [\hat{N} + \hat{N}_{\delta}] DenseMatrix<Number> Ke; // [\hat{K} + \hat{K}_{\delta}] DenseVector<Number> Fe; // [\hat{F} + \hat{F}_{\delta}] //DenseVector<Number> Fe_old; // element force vector (previous time) DenseVector<Number> h; // element enthalpy vector (previous time) DenseVector<Number> h_dot; //DenseVector<Number> delta_h_dot; DenseMatrix<Number> Mstar; // general time integration stiffness matrix (Eq. 125) DenseVector<Number> R; // general time integration force vector (Eq. 126) // Storage vectors for the degree of freedom indices std::vector<unsigned int> dof_indices; // this system (h) // std::vector<unsigned int> dof_indices_hdot; // std::vector<unsigned int> dof_indices_deltahdot; std::vector<unsigned int> dof_indices_velocity; // this system std::vector<unsigned int> dof_indices_rho; // ThermoEq density std::vector<unsigned int> dof_indices_tmp; // ThermoEq temperature std::vector<unsigned int> dof_indices_f; // ThermoEq liquid fraction std::vector<unsigned int> dof_indices_eps; // ThermoEq epsilon // Define the necessary constants const Number gamma = get_constant<Number>("gamma"); const Number dt = get_constant<Number>("dt"); // time step Real time = this->time; // current time const Number ks = thermo->get_constant<Number>("conductivity_solid"); const Number kf = thermo->get_constant<Number>("conductivity_fluid"); const Number cs = thermo->get_constant<Number>("specific_heat_solid"); const Number cf = thermo->get_constant<Number>("specific_heat_fluid"); const Number Te = thermo->get_constant<Number>("eutectic_temperature"); const Number hf = thermo->get_constant<Number>("latent_heat"); // Index of density variable in ThermoEq system const unsigned int rho_idx = thermo->variable_number("density"); const unsigned int tmp_idx = thermo->variable_number("temperature"); const unsigned int f_idx = thermo->variable_number("liquid_mass_fraction"); const unsigned int eps_idx = thermo->variable_number("epsilon"); // Loop over all the elements in the mesh that are on local processor MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el){ // Pointer to the element current element const Elem* elem = *el; // Get the degree of freedom indices for the current element dof_map.dof_indices(elem, dof_indices, 0); //dof_map.dof_indices(elem, dof_indices_hdot, 1); //dof_map.dof_indices(elem, dof_indices_deltahdot, 2); dof_map_momentum.dof_indices(elem, dof_indices_velocity); dof_map_thermo.dof_indices(elem, dof_indices_rho, rho_idx); dof_map_thermo.dof_indices(elem, dof_indices_tmp, tmp_idx); dof_map_thermo.dof_indices(elem, dof_indices_f, f_idx); dof_map_thermo.dof_indices(elem, dof_indices_eps, eps_idx); // Compute the element-specific data for the current element fe->reinit (elem); fe_thermo->reinit(elem); fe_momentum->reinit(elem); // Zero the element matrices and vectors Me.resize (dof_indices.size(), dof_indices.size()); // [\hat{M} + \hat{M}_{\delta}] Ne.resize (dof_indices.size(), dof_indices.size()); // Ke.resize (dof_indices.size(), dof_indices.size()); Fe.resize (dof_indices.size()); // Extract a vector of quadrature x,y,z coordinates const vector<Point> qp_vec = fe->get_xyz(); // Compute the element length, h Number elem_length = thermo->element_length(elem); // Compute the RHS and mass and stiffness matrix for this element (Me) for (unsigned int qp = 0; qp < qrule.n_points(); qp++){ // Get the velocity vector at this point (old value) VectorValue<Number> v; for (unsigned int i = 0; i < N_momentum.size(); i++){ for (unsigned int j = 0; j < dim; j++){ v(j) += N_momentum[i][qp] * momentum->old_solution(dof_indices_velocity[2*i+j]); } } // Compute ThermoEq variables; must be mapped from node to quadrature points Number T = 0; Gradient grad_T; Number f = 0; Gradient grad_f; Number rho = 0; Number rho_old = 0; Number eps = 0; for (unsigned int i = 0; i < N_thermo.size(); i++){ T += N_thermo[i][qp] * thermo->current_solution(dof_indices_tmp[i]); grad_T.add_scaled(B_thermo[i][qp], thermo->current_solution(dof_indices_tmp[i])); f += N_thermo[i][qp] * thermo->current_solution(dof_indices_f[i]); grad_f.add_scaled(B_thermo[i][qp], thermo->current_solution(dof_indices_f[i])); rho += N_thermo[i][qp] * thermo->current_solution(dof_indices_rho[i]); rho_old += N_thermo[i][qp] * thermo->old_solution(dof_indices_rho[i]); eps += N_thermo[i][qp] * thermo->current_solution(dof_indices_eps[i]); } // Compute EnergySystem variables Gradient grad_h; for (unsigned int i = 0; i < B.size(); i++){ grad_h.add_scaled(B[i][qp], this->current_solution(dof_indices[i])); } // Compute T_{,k}^h v_k^h and f_{,k} v_k^h summation terms for F Number Tv = 0; Number fv = 0; for (unsigned int i = 0; i < dim; i++){ Tv += grad_T(i) * v(i); fv += grad_f(i) * v(i); } // Compute the time derivative of density const Number drho_dt = (rho - rho_old)/dt; // Compute alpha term of Eq. 69 const Number alpha = this->alpha(grad_T, grad_h, f); // Extract tau_1 stabilization term const Number tau_1 = thermo->tau_1(qp_vec[qp], elem_length); // Loop through the components and construct matrices for (unsigned int i = 0; i < N.size(); i++){ // Compute advective stabilization term (Eq. A, p. 1777) const Number d = tau_1 * v * B[i][qp] / f - tau_1 * 1/rho * drho_dt * (1-f)/f * N[i][qp]; // Force vector, Eq. 77 Number F1 = JxW[qp] * (N[i][qp] + d) * rho * (1 - f) * (cf - cs) * Tv; Number F2 = JxW[qp] * (N[i][qp] + d) * rho * fv * ((cf - cs) * (T - Te) + hf); Number F3 = JxW[qp] * (N[i][qp] + d) * drho_dt * (1 - f) * ((cf - cs) * (T - Te) + hf); Fe(i) += F1 + F2 + F3; // Build the stiffness matrices for (unsigned int j = 0; j < N.size(); j++){ // Mass matrix, Eq. 108 Me(i,j) += JxW[qp] * rho * ((N[i][qp] + d) * N[j][qp]); // Stiffness matrix one, Ne, Eq. 109 Ne(i,j) += JxW[qp] * rho * ((N[i][qp] + d) * (v * B[j][qp])); // Stiffness matrix two, Ke, Eq. 110 Ke(i,j) += JxW[qp]*((eps*kf + (1 - eps)*ks) * alpha * B[i][qp] * B[j][qp]); } } } printf("Me:\n"); Me.print(std::cout); printf("\nNe:\n"); Ne.print(std::cout); printf("\nKe:\n"); Ke.print(std::cout); printf("\nFe:\n"); Fe.print(std::cout); h.resize(dof_indices.size()); h_dot.resize(dof_indices.size()); // delta_h_dot.resize(dof_indices_deltahdot.size()); for (unsigned int i = 0; i < dof_indices.size(); i++){ h(i) = this->old_solution(dof_indices[i]); h_dot(i) = this->get_vector("h_dot")(dof_indices[i]); // delta_h_dot(i) = this->old_solution(dof_indices_deltahdot[i]); } this->get_matrix("M").add_matrix(Me, dof_indices); this->get_matrix("N").add_matrix(Ne, dof_indices); this->get_matrix("K").add_matrix(Ke, dof_indices); this->get_vector("F").add_vector(Fe, dof_indices); Mstar.resize(dof_indices.size(), dof_indices.size()); R.resize(dof_indices.size()); // Me + gamma*dt*(Ke + Ne); Mstar.add(1,Me); Mstar.add(gamma*dt,Ke); Mstar.add(gamma*dt,Ne); this->matrix->add_matrix(Mstar, dof_indices); R.add(1,Fe); DenseVector<Number> a(dof_indices.size()); Me.vector_mult(a, h_dot); R.add(-1, a); DenseMatrix<Number> B(dof_indices.size(), dof_indices.size()); DenseVector<Number> b(dof_indices.size()); B.add(1,Ne); B.add(1,Ke); B.vector_mult(b, h); R.add(-1,b); this->rhs->add_vector(R, dof_indices); /* // BOUNDARY CONDITIONS // Loop through each side of the element for applying boundary conditions for (unsigned int s = 0; s < elem->n_sides(); s++){ // Only consider the side if it does not have a neighbor if (elem->neighbor(s) == NULL){ // Pointer to current element side const AutoPtr<Elem> side = elem->side(s); // Boundary ID of the current side int boundary_id = (mesh.boundary_info)->boundary_id(elem, s); // Get index of the boundary class with the same id // this vector is empty if there is no match and only // contains a single value if there is a match std::vector<int> idx = get_boundary_index(boundary_id); // Continue of there is a match if(!idx.empty()){ // Compute the shape function values on the element face fe_face->reinit(elem, s); // Create a shared pointer to the boundary class boost::shared_ptr<HeatEqBoundaryBase> ptr = bc_ptrs[idx[0]]; // Determine the type of boundary considered std::string type = ptr->type; // Loop through quadrature points for (unsigned int qp = 0; qp < qface.n_points(); qp++){ // DIRICHLET (libMesh version; handled at initialization) if(type.compare("dirichlet") == 0){ // The dirichlet conditions are handled at initlization // but I don't want to throw an error if they are // encountered, so just do nothing // NEUMANN condition } else if(type.compare("neumann") == 0){ // Current and past flux values const Number q = ptr->q(qface_points[qp], time); const Number q_old = ptr->q(qface_points[qp], time - dt); // Add values to Fe for (unsigned int i = 0; i < psi.size(); i++){ Fe(i) += JxW_face[qp] * q * psi[i][qp]; Fe_old(i) += JxW_face[qp] * q_old * psi[i][qp]; } // CONVECTION boundary } else if(type.compare("convection") == 0){ // Current and past h and T_inf const Number h = ptr->h(qface_points[qp], time); const Number h_old = ptr->h(qface_points[qp], time - dt); const Number Tinf = ptr->Tinf(qface_points[qp], time); const Number Tinf_old = ptr->Tinf(qface_points[qp], time - dt); // Add values to Ke and Fe for (unsigned int i = 0; i < psi.size(); i++){ Fe(i) += (1) * JxW_face[qp] * h * Tinf * psi[i][qp]; Fe_old(i) += (1) * JxW_face[qp] * h_old * Tinf_old * psi[i][qp]; for (unsigned int j = 0; j < psi.size(); j++){ Ke(i,j) += JxW_face[qp] * psi[i][qp] * h * psi[j][qp]; } } // Un-registerd type } else { printf("WARNING! The boundary type, %s, was not understood!\n", type.c_str()); } // (end) type.compare(...) statemenst } //(end) for (int qp = 0; qp < qface.n_points(); qp++) } // (end) if(!idx.empty) } // (end) if (elem->neighbor(s) == NULL){ } // (end) for (int s = 0; s < elem->n_sides(); s++) // Zero the pervious time-step temperature vector for this element u_old.resize(dof_indices.size()); // Gather the temperatures at the nodes for (unsigned int i = 0; i < psi.size(); i++){ u_old(i) = this->old_solution(dof_indices[i]); } // Build K_hat and F_hat (appends existing) K_hat.resize(dof_indices.size(), dof_indices.size()); F_hat.resize(dof_indices.size()); build_stiffness_and_rhs(K_hat, F_hat, Me, Ke, Fe_old, Fe, u_old, dt, theta); // Applies the dirichlet constraints to K_hat and F_hat dof_map.heterogenously_constrain_element_matrix_and_vector(K_hat, F_hat, dof_indices); // Apply the local components to the global K and F this->matrix->add_matrix(K_hat, dof_indices); this->rhs->add_vector(F_hat, dof_indices); */ } // (end) for ( ; el != end_el; ++el) //update_rhs(); } // (end) assemble()
// The matrix assembly function to be called at each time step to // prepare for the linear solve. void assemble_solid (EquationSystems& es, const std::string& system_name) { //es.print_info(); #if LOG_ASSEMBLE_PERFORMANCE PerfLog perf_log("Assemble"); perf_log.push("assemble stiffness"); #endif // Get a reference to the auxiliary system //TransientExplicitSystem& aux_system = es.get_system<TransientExplicitSystem>("Newton-update"); // It is a good idea to make sure we are assembling // the proper system. libmesh_assert (system_name == "Newton-update"); // Get a constant reference to the mesh object. const MeshBase& mesh = es.get_mesh(); // The dimension that we are running const unsigned int dim = mesh.mesh_dimension(); // Get a reference to the Stokes system object. TransientLinearImplicitSystem & newton_update = es.get_system<TransientLinearImplicitSystem> ("Newton-update"); // New TransientLinearImplicitSystem & last_non_linear_soln = es.get_system<TransientLinearImplicitSystem> ("Last-non-linear-soln"); TransientLinearImplicitSystem & fluid_system_vel = es.get_system<TransientLinearImplicitSystem> ("fluid-system-vel"); #if VELOCITY TransientLinearImplicitSystem& velocity = es.get_system<TransientLinearImplicitSystem>("velocity-system"); #endif #if UN_MINUS_ONE TransientLinearImplicitSystem & unm1 = es.get_system<TransientLinearImplicitSystem> ("unm1-system"); #endif test(62); const System & ref_sys = es.get_system("Reference-Configuration"); test(63); // Numeric ids corresponding to each variable in the system const unsigned int u_var = last_non_linear_soln .variable_number ("u"); const unsigned int v_var = last_non_linear_soln .variable_number ("v"); const unsigned int w_var = last_non_linear_soln .variable_number ("w"); #if INCOMPRESSIBLE const unsigned int p_var = last_non_linear_soln .variable_number ("p"); #endif #if FLUID_P_CONST const unsigned int m_var = fluid_system_vel.variable_number ("fluid_M"); std::vector<unsigned int> dof_indices_m; #endif // Get the Finite Element type for "u". Note this will be // the same as the type for "v". FEType fe_vel_type = last_non_linear_soln.variable_type(u_var); test(64); #if INCOMPRESSIBLE // Get the Finite Element type for "p". FEType fe_pres_type = last_non_linear_soln .variable_type(p_var); #endif // Build a Finite Element object of the specified type for // the velocity variables. AutoPtr<FEBase> fe_vel (FEBase::build(dim, fe_vel_type)); #if INCOMPRESSIBLE // Build a Finite Element object of the specified type for // the pressure variables. AutoPtr<FEBase> fe_pres (FEBase::build(dim, fe_pres_type)); #endif // A Gauss quadrature rule for numerical integration. // Let the \p FEType object decide what order rule is appropriate. QGauss qrule (dim, fe_vel_type.default_quadrature_order()); // Tell the finite element objects to use our quadrature rule. fe_vel->attach_quadrature_rule (&qrule); test(65); // AutoPtr<QBase> qrule2(fe_vel_type.default_quadrature_rule(dim)); // fe_vel->attach_quadrature_rule (qrule2.get()); #if INCOMPRESSIBLE fe_pres->attach_quadrature_rule (&qrule); #endif // The element Jacobian * quadrature weight at each integration point. const std::vector<Real>& JxW = fe_vel->get_JxW(); // The element shape functions evaluated at the quadrature points. const std::vector<std::vector<Real> >& phi = fe_vel->get_phi(); // The element shape function gradients for the velocity // variables evaluated at the quadrature points. const std::vector<std::vector<RealGradient> >& dphi = fe_vel->get_dphi(); test(66); #if INCOMPRESSIBLE // The element shape functions for the pressure variable // evaluated at the quadrature points. const std::vector<std::vector<Real> >& psi = fe_pres->get_phi(); #endif const std::vector<Point>& coords = fe_vel->get_xyz(); // A reference to the \p DofMap object for this system. The \p DofMap // object handles the index translation from node and element numbers // to degree of freedom numbers. We will talk more about the \p DofMap // in future examples. const DofMap & dof_map = last_non_linear_soln .get_dof_map(); #if FLUID_P_CONST const DofMap & dof_map_fluid = fluid_system_vel .get_dof_map(); #endif // K will be the jacobian // F will be the Residual DenseMatrix<Number> Ke; DenseVector<Number> Fe; DenseSubMatrix<Number> Kuu(Ke), Kuv(Ke), Kuw(Ke), Kvu(Ke), Kvv(Ke), Kvw(Ke), Kwu(Ke), Kwv(Ke), Kww(Ke); #if INCOMPRESSIBLE DenseSubMatrix<Number> Kup(Ke),Kvp(Ke),Kwp(Ke), Kpu(Ke), Kpv(Ke), Kpw(Ke), Kpp(Ke); #endif; DenseSubVector<Number> Fu(Fe), Fv(Fe), Fw(Fe); #if INCOMPRESSIBLE DenseSubVector<Number> Fp(Fe); #endif // This vector will hold the degree of freedom indices for // the element. These define where in the global system // the element degrees of freedom get mapped. std::vector<unsigned int> dof_indices; std::vector<unsigned int> dof_indices_u; std::vector<unsigned int> dof_indices_v; std::vector<unsigned int> dof_indices_w; #if INCOMPRESSIBLE std::vector<unsigned int> dof_indices_p; #endif #if INERTIA test(67); const unsigned int a_var = last_non_linear_soln.variable_number ("a"); const unsigned int b_var = last_non_linear_soln.variable_number ("b"); const unsigned int c_var = last_non_linear_soln.variable_number ("c"); //B block DenseSubMatrix<Number> Kua(Ke), Kub(Ke), Kuc(Ke), Kva(Ke), Kvb(Ke), Kvc(Ke), Kwa(Ke), Kwb(Ke), Kwc(Ke); //C block DenseSubMatrix<Number> Kau(Ke), Kav(Ke), Kaw(Ke), Kbu(Ke), Kbv(Ke), Kbw(Ke), Kcu(Ke), Kcv(Ke), Kcw(Ke); //D block DenseSubMatrix<Number> Kaa(Ke), Kab(Ke), Kac(Ke), Kba(Ke), Kbb(Ke), Kbc(Ke), Kca(Ke), Kcb(Ke), Kcc(Ke); DenseSubVector<Number> Fa(Fe), Fb(Fe), Fc(Fe); std::vector<unsigned int> dof_indices_a; std::vector<unsigned int> dof_indices_b; std::vector<unsigned int> dof_indices_c; test(68); #endif DenseMatrix<Real> stiff; DenseVector<Real> res; VectorValue<Gradient> grad_u_mat; VectorValue<Gradient> grad_u_mat_old; const Real dt = es.parameters.get<Real>("dt"); const Real progress = es.parameters.get<Real>("progress"); #if PORO DenseVector<Real> p_stiff; DenseVector<Real> p_res; PoroelasticConfig material(dphi,psi); #endif // Just calculate jacobian contribution when we need to material.calculate_linearized_stiffness = true; MeshBase::const_element_iterator el = mesh.active_local_elements_begin(); const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end(); for ( ; el != end_el; ++el) { test(69); const Elem* elem = *el; dof_map.dof_indices (elem, dof_indices); dof_map.dof_indices (elem, dof_indices_u, u_var); dof_map.dof_indices (elem, dof_indices_v, v_var); dof_map.dof_indices (elem, dof_indices_w, w_var); #if INCOMPRESSIBLE dof_map.dof_indices (elem, dof_indices_p, p_var); #endif const unsigned int n_dofs = dof_indices.size(); const unsigned int n_u_dofs = dof_indices_u.size(); const unsigned int n_v_dofs = dof_indices_v.size(); const unsigned int n_w_dofs = dof_indices_w.size(); #if INCOMPRESSIBLE const unsigned int n_p_dofs = dof_indices_p.size(); #endif #if FLUID_P_CONST dof_map_fluid.dof_indices (elem, dof_indices_m, m_var); #endif //elem->print_info(); fe_vel->reinit (elem); #if INCOMPRESSIBLE fe_pres->reinit (elem); #endif Ke.resize (n_dofs, n_dofs); Fe.resize (n_dofs); Kuu.reposition (u_var*n_u_dofs, u_var*n_u_dofs, n_u_dofs, n_u_dofs); Kuv.reposition (u_var*n_u_dofs, v_var*n_u_dofs, n_u_dofs, n_v_dofs); Kuw.reposition (u_var*n_u_dofs, w_var*n_u_dofs, n_u_dofs, n_w_dofs); #if INCOMPRESSIBLE Kup.reposition (u_var*n_u_dofs, p_var*n_u_dofs, n_u_dofs, n_p_dofs); #endif Kvu.reposition (v_var*n_v_dofs, u_var*n_v_dofs, n_v_dofs, n_u_dofs); Kvv.reposition (v_var*n_v_dofs, v_var*n_v_dofs, n_v_dofs, n_v_dofs); Kvw.reposition (v_var*n_v_dofs, w_var*n_v_dofs, n_v_dofs, n_w_dofs); #if INCOMPRESSIBLE Kvp.reposition (v_var*n_v_dofs, p_var*n_v_dofs, n_v_dofs, n_p_dofs); #endif Kwu.reposition (w_var*n_w_dofs, u_var*n_w_dofs, n_w_dofs, n_u_dofs); Kwv.reposition (w_var*n_w_dofs, v_var*n_w_dofs, n_w_dofs, n_v_dofs); Kww.reposition (w_var*n_w_dofs, w_var*n_w_dofs, n_w_dofs, n_w_dofs); #if INCOMPRESSIBLE Kwp.reposition (w_var*n_w_dofs, p_var*n_w_dofs, n_w_dofs, n_p_dofs); Kpu.reposition (p_var*n_u_dofs, u_var*n_u_dofs, n_p_dofs, n_u_dofs); Kpv.reposition (p_var*n_u_dofs, v_var*n_u_dofs, n_p_dofs, n_v_dofs); Kpw.reposition (p_var*n_u_dofs, w_var*n_u_dofs, n_p_dofs, n_w_dofs); Kpp.reposition (p_var*n_u_dofs, p_var*n_u_dofs, n_p_dofs, n_p_dofs); #endif Fu.reposition (u_var*n_u_dofs, n_u_dofs); Fv.reposition (v_var*n_u_dofs, n_v_dofs); Fw.reposition (w_var*n_u_dofs, n_w_dofs); #if INCOMPRESSIBLE Fp.reposition (p_var*n_u_dofs, n_p_dofs); #endif #if INERTIA //B block Kua.reposition (u_var*n_u_dofs, 3*n_u_dofs + n_p_dofs, n_u_dofs, n_u_dofs); Kub.reposition (u_var*n_u_dofs, 4*n_u_dofs + n_p_dofs, n_u_dofs, n_v_dofs); Kuc.reposition (u_var*n_u_dofs, 5*n_u_dofs + n_p_dofs, n_u_dofs, n_w_dofs); Kva.reposition (v_var*n_v_dofs, 3*n_u_dofs + n_p_dofs, n_v_dofs, n_u_dofs); Kvb.reposition (v_var*n_v_dofs, 4*n_u_dofs + n_p_dofs, n_v_dofs, n_v_dofs); Kvc.reposition (v_var*n_v_dofs, 5*n_u_dofs + n_p_dofs, n_v_dofs, n_w_dofs); Kwa.reposition (w_var*n_w_dofs, 3*n_u_dofs + n_p_dofs, n_w_dofs, n_u_dofs); Kwb.reposition (w_var*n_w_dofs, 4*n_u_dofs + n_p_dofs, n_w_dofs, n_v_dofs); Kwc.reposition (w_var*n_w_dofs, 5*n_u_dofs + n_p_dofs, n_w_dofs, n_w_dofs); test(701); //C block Kau.reposition (3*n_u_dofs + n_p_dofs, u_var*n_u_dofs, n_u_dofs, n_u_dofs); Kav.reposition (3*n_u_dofs + n_p_dofs, v_var*n_u_dofs, n_u_dofs, n_v_dofs); Kaw.reposition (3*n_u_dofs + n_p_dofs, w_var*n_u_dofs, n_u_dofs, n_w_dofs); Kbu.reposition (4*n_u_dofs + n_p_dofs, u_var*n_v_dofs, n_v_dofs, n_u_dofs); Kbv.reposition (4*n_u_dofs + n_p_dofs, v_var*n_v_dofs, n_v_dofs, n_v_dofs); Kbw.reposition (4*n_u_dofs + n_p_dofs, w_var*n_v_dofs, n_v_dofs, n_w_dofs); Kcu.reposition (5*n_u_dofs + n_p_dofs, u_var*n_w_dofs, n_w_dofs, n_u_dofs); Kcv.reposition (5*n_u_dofs + n_p_dofs, v_var*n_w_dofs, n_w_dofs, n_v_dofs); Kcw.reposition (5*n_u_dofs + n_p_dofs, w_var*n_w_dofs, n_w_dofs, n_w_dofs); //D block Kaa.reposition (3*n_u_dofs + n_p_dofs, 3*n_u_dofs + n_p_dofs, n_u_dofs, n_u_dofs); Kab.reposition (3*n_u_dofs + n_p_dofs, 4*n_u_dofs + n_p_dofs, n_u_dofs, n_v_dofs); Kac.reposition (3*n_u_dofs + n_p_dofs, 5*n_u_dofs + n_p_dofs, n_u_dofs, n_w_dofs); Kba.reposition (4*n_u_dofs + n_p_dofs, 3*n_u_dofs + n_p_dofs, n_v_dofs, n_u_dofs); Kbb.reposition (4*n_u_dofs + n_p_dofs, 4*n_u_dofs + n_p_dofs, n_v_dofs, n_v_dofs); Kbc.reposition (4*n_u_dofs + n_p_dofs, 5*n_u_dofs + n_p_dofs, n_v_dofs, n_w_dofs); Kca.reposition (5*n_u_dofs + n_p_dofs, 3*n_u_dofs + n_p_dofs, n_w_dofs, n_u_dofs); Kcb.reposition (5*n_u_dofs + n_p_dofs, 4*n_u_dofs + n_p_dofs, n_w_dofs, n_v_dofs); Kcc.reposition (5*n_u_dofs + n_p_dofs, 5*n_u_dofs + n_p_dofs, n_w_dofs, n_w_dofs); Fa.reposition (3*n_u_dofs + n_p_dofs, n_u_dofs); Fb.reposition (4*n_u_dofs + n_p_dofs, n_v_dofs); Fc.reposition (5*n_u_dofs + n_p_dofs, n_w_dofs); dof_map.dof_indices (elem, dof_indices_a, a_var); dof_map.dof_indices (elem, dof_indices_b, b_var); dof_map.dof_indices (elem, dof_indices_c, c_var); test(71); #endif System& aux_system = es.get_system<System>("Reference-Configuration"); std::vector<unsigned int> undefo_index; std::vector<unsigned int> vel_index; for (unsigned int qp=0; qp<qrule.n_points(); qp++) { Point rX; for (unsigned int l=0; l<n_u_dofs; l++) { rX(0) += phi[l][qp]*ref_sys.current_local_solution->el(dof_indices_u[l]); rX(1) += phi[l][qp]*ref_sys.current_local_solution->el(dof_indices_v[l]); rX(2) += phi[l][qp]*ref_sys.current_local_solution->el(dof_indices_w[l]); } #if INERTIA || DT test(72); Real rho_s=15; Point current_x; for (unsigned int l=0; l<n_u_dofs; l++) { current_x(0) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_u[l]); current_x(1) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_v[l]); current_x(2) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_w[l]); } Point old_x; for (unsigned int l=0; l<n_u_dofs; l++) { old_x(0) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_u[l]); old_x(1) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_v[l]); old_x(2) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_w[l]); } #if INERTIA Point old_vel; for (unsigned int l=0; l<n_u_dofs; l++) { old_vel(0) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_a[l]); old_vel(1) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_b[l]); old_vel(2) += phi[l][qp]*last_non_linear_soln.old_local_solution->el(dof_indices_c[l]); } Point current_vel; for (unsigned int l=0; l<n_u_dofs; l++) { current_vel(0) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_a[l]); current_vel(1) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_b[l]); current_vel(2) += phi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_c[l]); } #endif #if UN_MINUS_ONE Point unm1_x; for (unsigned int l=0; l<n_u_dofs; l++) { unm1_x(0) += phi[l][qp]*unm1.old_local_solution->el(dof_indices_u[l]); unm1_x(1) += phi[l][qp]*unm1.old_local_solution->el(dof_indices_v[l]); unm1_x(2) += phi[l][qp]*unm1.old_local_solution->el(dof_indices_w[l]); } #endif Point value_acc; Point value_acc_alt; #if DT for (unsigned int d = 0; d < dim; ++d) { value_acc_alt(d) = (rho_s)*( ((current_x(d)-rX(d))-(old_x(d)-rX(d)))-((old_x(d)-rX(d))- (unm1_x(d)-rX(d))) ); value_acc(d) = (rho_s)*((current_x(d))-2*(old_x(d))+ (unm1_x(d))); value_acc(d) = (rho_s)*((current_x(d))-(old_x(d))); } #endif Point res_1; Point res_2; #if INERTIA for (unsigned int d = 0; d < dim; ++d) { res_1(d) = (rho_s)*((current_vel(d))-(old_vel(d))); res_2(d) = current_x(d)-dt*current_vel(d)-old_x(d); } /* std::cout<<" current_vel "<<current_vel<<std::endl; std::cout<<" res_1 "<<res_1<<std::endl; std::cout<<" res_2 "<<res_2<<std::endl; */ #endif test(73); #endif Number p_solid = 0.; #if MOVING_MESH grad_u_mat(0) = grad_u_mat(1) = grad_u_mat(2) = 0; for (unsigned int d = 0; d < dim; ++d) { std::vector<Number> u_undefo; //Fills the vector di with the global degree of freedom indices for the element. :dof_indicies aux_system.get_dof_map().dof_indices(elem, undefo_index,d); aux_system.current_local_solution->get(undefo_index, u_undefo); for (unsigned int l = 0; l != n_u_dofs; l++) grad_u_mat(d).add_scaled(dphi[l][qp], u_undefo[l]); } #endif //#include "fixed_mesh_in_solid_assemble_code.txt" #if INCOMPRESSIBLE for (unsigned int l=0; l<n_p_dofs; l++) { p_solid += psi[l][qp]*last_non_linear_soln.current_local_solution->el(dof_indices_p[l]); } #endif #if INCOMPRESSIBLE Real m=0; Real p_fluid=0; #if FLUID_VEL for (unsigned int l=0; l<n_p_dofs; l++) { p_fluid += psi[l][qp]*fluid_system_vel.current_local_solution->el(dof_indices_p[l]); } //As outlined in Chappel p=(p_curr-p_old)/2 Real p_fluid_old=0; for (unsigned int l=0; l<n_p_dofs; l++) { p_fluid_old += psi[l][qp]*fluid_system_vel.old_local_solution->el(dof_indices_p[l]); } p_fluid=0.5*p_fluid+0.5*p_fluid_old; Real m_old=0; #if FLUID_P_CONST for (unsigned int l=0; l<n_p_dofs; l++) { m += psi[l][qp]*fluid_system_vel.current_local_solution->el(dof_indices_m[l]); } for (unsigned int l=0; l<n_p_dofs; l++) { m_old += psi[l][qp]*fluid_system_vel.old_local_solution->el(dof_indices_m[l]); } #endif material.init_for_qp(grad_u_mat, p_solid, qp, 1.0*m+0.0*m_old, p_fluid); #endif #endif //#if INCOMPRESSIBLE #if INCOMPRESSIBLE && ! PORO material.init_for_qp(grad_u_mat, p_solid, qp); #endif for (unsigned int i=0; i<n_u_dofs; i++) { res.resize(dim); material.get_residual(res, i); res.scale(JxW[qp]); #if INERTIA res.scale(dt); #endif #if DT res.scale(dt); #endif //std::cout<< "res "<<res<<std::endl; Fu(i) += res(0); Fv(i) += res(1) ; Fw(i) += res(2); #if GRAVITY Real grav=0.0; Fu(i) += progress*grav*JxW[qp]*phi[i][qp]; #endif #if INERTIA Fu(i) += JxW[qp]*phi[i][qp]*res_1(0); Fv(i) += JxW[qp]*phi[i][qp]*res_1(1); Fw(i) += JxW[qp]*phi[i][qp]*res_1(2); Fa(i) += JxW[qp]*phi[i][qp]*res_2(0); Fb(i) += JxW[qp]*phi[i][qp]*res_2(1); Fc(i) += JxW[qp]*phi[i][qp]*res_2(2); #endif // Matrix contributions for the uu and vv couplings. for (unsigned int j=0; j<n_u_dofs; j++) { material.get_linearized_stiffness(stiff, i, j); stiff.scale(JxW[qp]); #if DT res.scale(dt); #endif #if INERTIA stiff.scale(dt); Kua(i,j)+= rho_s*JxW[qp]*phi[i][qp]*phi[j][qp]; Kvb(i,j)+= rho_s*JxW[qp]*phi[i][qp]*phi[j][qp]; Kwc(i,j)+= rho_s*JxW[qp]*phi[i][qp]*phi[j][qp]; Kau(i,j)+= JxW[qp]*phi[i][qp]*phi[j][qp]; Kbv(i,j)+= JxW[qp]*phi[i][qp]*phi[j][qp]; Kcw(i,j)+= JxW[qp]*phi[i][qp]*phi[j][qp]; Kaa(i,j)+= -dt*JxW[qp]*phi[i][qp]*phi[j][qp]; Kbb(i,j)+= -dt*JxW[qp]*phi[i][qp]*phi[j][qp]; Kcc(i,j)+= -dt*JxW[qp]*phi[i][qp]*phi[j][qp]; #endif Kuu(i,j)+= stiff(u_var, u_var); Kuv(i,j)+= stiff(u_var, v_var); Kuw(i,j)+= stiff(u_var, w_var); Kvu(i,j)+= stiff(v_var, u_var); Kvv(i,j)+= stiff(v_var, v_var); Kvw(i,j)+= stiff(v_var, w_var); Kwu(i,j)+= stiff(w_var, u_var); Kwv(i,j)+= stiff(w_var, v_var); Kww(i,j)+= stiff(w_var, w_var); #if GRAVITY Kuu(i,j)+= 1*JxW[qp]*phi[i][qp]*phi[j][qp]; #endif } } #if INCOMPRESSIBLE && FLUID_P_CONST for (unsigned int i = 0; i < n_p_dofs; i++) { material.get_p_residual(p_res, i); p_res.scale(JxW[qp]); Fp(i) += p_res(0); } for (unsigned int i = 0; i < n_u_dofs; i++) { for (unsigned int j = 0; j < n_p_dofs; j++) { material.get_linearized_uvw_p_stiffness(p_stiff, i, j); p_stiff.scale(JxW[qp]); Kup(i, j) += p_stiff(0); Kvp(i, j) += p_stiff(1); Kwp(i, j) += p_stiff(2); } } for (unsigned int i = 0; i < n_p_dofs; i++) { for (unsigned int j = 0; j < n_u_dofs; j++) { material.get_linearized_p_uvw_stiffness(p_stiff, i, j); p_stiff.scale(JxW[qp]); Kpu(i, j) += p_stiff(0); Kpv(i, j) += p_stiff(1); Kpw(i, j) += p_stiff(2); } } #endif #if CHAP && ! FLUID_P_CONST for (unsigned int i = 0; i < n_p_dofs; i++) { Fp(i) += 0*JxW[qp]*psi[i][qp]; } for (unsigned int i = 0; i < n_p_dofs; i++) { for (unsigned int j = 0; j < n_p_dofs; j++) { Kpp(i, j) += 1*JxW[qp]*psi[i][qp]*psi[j][qp]; } } #endif }//end of qp loop newton_update.matrix->add_matrix (Ke, dof_indices); newton_update.rhs->add_vector (Fe, dof_indices); } // end of element loop // dof_map.constrain_element_matrix_and_vector (Ke, Fe, dof_indices); newton_update.rhs->close(); newton_update.matrix->close(); #if LOG_ASSEMBLE_PERFORMANCE perf_log.pop("assemble stiffness"); #endif #if LOG_ASSEMBLE_PERFORMANCE perf_log.push("assemble bcs"); #endif //Assemble the boundary conditions. assemble_bcs(es); #if LOG_ASSEMBLE_PERFORMANCE perf_log.pop("assemble bcs"); #endif std::ofstream lhs_out("lhsoutS3.dat"); Ke.print(lhs_out); lhs_out.close(); return; }