Void Mat::MakeDiag(Real k) { Int i, j; for (i = 0; i < Rows(); i++) for (j = 0; j < Cols(); j++) if (i == j) Elt(i,j) = k; else Elt(i,j) = vl_zero; }
// // Finds the element with the largest coefficient contained in the minimal coefficients // BUBBLE functins are considered only. // void OdeProb::MaxMinCoef(EltInfo& eltInfo) const { double coef, minCoef; eltInfo.m_maxMinCoef = 0; // Initialization for(size_t n = 0; n < EltNo(); n++) // For each element { const Element& e = Elt(n); minCoef = DBL_MAX; for(size_t j = 1; j < e.DofNo() - 1; j++) // For each BUBBLE DOF in element { const int dof = e.m_dof[j]; if(dof < 0) // Skip Dirichlet boundary conditions continue; // Find the smallest coefficient for element "e" coef = fabs(m_y->Get(dof)); if(coef < minCoef) minCoef = coef; } // Set the largest coefficient with minimal coefficients if(minCoef > eltInfo.m_maxMinCoef) { eltInfo.m_eltId = n; eltInfo.m_maxMinCoef = minCoef; eltInfo.m_eigVal = 0; } } }
Void Mat::MakeBlock() { Int i, j; for (i = 0; i < Rows(); i++) for (j = 0; j < Cols(); j++) Elt(i,j) = vl_one; }
Void Mat::MakeDiag() { Int i, j; for (i = 0; i < Rows(); i++) for (j = 0; j < Cols(); j++) Elt(i,j) = (i == j) ? vl_one : vl_zero; }
// // Assembling algorithm for equation solving // void OdeProb::Assemble() { size_t i, j, psiI, psiJ; int ni; // row position in matrix S int nj; // column position in matrix S // const size_t M = Dim(); const size_t N = EltNo(); // Number of elements // const double bndr[3] = {0, m_left.m_val, m_right.m_val}; // Element loop for(size_t n = 0; n < N; n++) { const Element& e = Elt(n); const size_t DofNo = e.DofNo(); // Loop over basis functions for(i = 0; i < DofNo; i++) { ni = e.m_dof[i]; if(ni < 0) continue; psiI = e.PsiId(i); // Loop over basis functions for(j = i; j < DofNo; j++) { psiJ = e.PsiId(j); nj = e.m_dof[j]; if(nj > -1) m_s->Set(ni, nj) += CalcS(e, psiI, psiJ); //else // Dirichlet boundary conditions are ZERO, hence it can be skiped // m_b->Set(ni) -= bndr[-nj] * CalcS(e, psiI, psiJ); } // Contribution of the vertex basis function $v_{m_1}$ to the right hand side $b$ m_b->Set(ni) += CalcB(e, psiI); } } }
// // Returns the value of the solution at $x$ // double OdeProb::GetSol(double x) const { int m1; // The equation must be solved! assert(m_y); assert(IsInRange(x)); const size_t n = FindElt(x); const Element& e = Elt(n); // s - Locat coordiante for element "e" const double s = std::min(std::max(e.Xinv(x), -1.0), 1.0); // MIN, MAX - To avoid the rounding errors // Sum over all basis function with support on the element $e$ double val = 0; /* // Left vertex basis function m1 = e.m_dof.front(); if(m1 > -1) val += m_y->Get(m1) * Basis(0, s); else { // Apply the Dirichlet boundary conditions if(m_left.m_type == BndrType_Dir) val += m_left.m_val * Basis(0, s); } // Right vertex basis function m1 = e.m_dof.back(); if(m1 > -1) val += m_y->Get(m1) * Basis(1, s); else { // Apply the Dirichlet boundary conditions if(m_right.m_type == BndrType_Dir) val += m_right.m_val * Basis(1, s); } // Bubble basis functions for(size_t j = 1; j < e.m_dof.size() - 1; j++) { m1 = e.m_dof[j]; val += m_y->Get(m1) * Basis(j, s); } */ // It works only with zero Dirichlet bpundary conditions for(size_t i = 0; i < e.m_dof.size(); i++) { const int m = e.m_dof[i]; if(m < 0) continue; const size_t psiI = e.PsiId(i); val += m_y->Get(m) * Basis(psiI, s); } // Non-zero Dirichlet bpundary conditions are applied { // Left vertex basis function assert(m_left.m_type == BndrType_Dir); m1 = e.m_dof.front(); if(m1 < 0) { const size_t psiI = e.PsiId(0); val += m_left.m_val * Basis(psiI, s); } // Right vertex basis function assert(m_right.m_type == BndrType_Dir); m1 = e.m_dof.back(); if(m1 < 0) { const size_t psiI = e.PsiId(1); val += m_right.m_val * Basis(psiI, s); } } return val; }