Esempio n. 1
0
// Updates the current Lhs and rhs based of the m_newVelocities guess
bool ImplicitStepper::updateLinearSystem( const VecXx solverForces )
{ //DK: this is where the lineic stretch gets checked and a possible update is applied
    StrandDynamics& dynamics = m_strand.dynamics();
    m_strand.requireExactJacobian( false );
    dynamics.setDisplacements( m_dt * m_futureVelocities ); // updated in NonLinearForce from Bogus, pushing updates 
    
    const Scalar stretchE = getLineicStretch();
    bool needUpdate = stretchE > m_stretchingFailureThreshold;
    Scalar residual = 0;
    if( !needUpdate )
    {
        computeRHS();
        dynamics.getScriptingController()->fixRHS( m_rhs );
        m_usedNonlinearSolver = true;

        //Below should be present, turning off because usually causes needUpdate to occur when stretching is small
        residual = ( m_rhs + solverForces ).squaredNorm() / m_rhs.rows();
        // needUpdate = residual > m_costretchResidualFailureThreshold;

    }
        
    if( needUpdate ) // DK: if residual or stretchE too big.
    { // solveLinear causes less stretching

        solveLinear();
        // solveNonLinear();
    }
        // std::cout << needUpdate << " stretchE: " << stretchE << " | " << m_stretchingFailureThreshold << " ||| residual: " << residual << " | " << m_costretchResidualFailureThreshold << std::endl;
    
    return needUpdate; // DK: now returns true if needs update
}
Esempio n. 2
0
void ImplicitStepper::solveLinear()
{
    computeRHS();
    computeLHS();

    Lhs().multiply( m_rhs, 1.0, m_futureVelocities );
    m_strand.dynamics().getScriptingController()->fixLHSAndRHS( Lhs(), m_rhs, m_dt );
    m_linearSolver.store( Lhs() );
}
Esempio n. 3
0
void stepSolution(char *stepType,GRID *g,SOLN *s,double dt,double *l2norm)
{
  double     coef;
  static int istep=0;
  int        i,k,l;
  int        nsubiter=20;
  double     CFL;

  // create temp variable for CFL number
  CFL = g->CFL;

  if (strcmp(stepType,"euler")==0)
  {
    computeRHS(g,s,l2norm);
    coef = 1.0;
    updateSoln(s->q,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
  }
  else if (strcmp(stepType,"rk3") == 0)
  {
    // RK step 1
    computeRHS(g,s,l2norm);
    coef=0.25;
    updateSoln(s->q,s->qt,s->r,s->sigma,dt,CFL,coef,g->ncells);
    coef=8.0/15;
    updateSoln(s->q,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
    
    // RK step 2 
    computeRHS(g,s,l2norm);
    coef=5.0/12;
    updateSoln(s->qt,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
    
    // RK step 3
    computeRHS(g,s,l2norm);
    coef=3.0/4.0;
    updateSoln(s->qt,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
  }
  else if (strcmp(stepType,"ADI")==0)
  {
    computeRHSk(g,s,l2norm);
    ADI(g,s,s->cflnum,dt);
  }
  else if (strcmp(stepType,"DADI")==0)
  {
    computeRHSk(g,s,l2norm);
    DADI(g,s,s->cflnum,dt);
  }
  else if (strcmp(stepType,"Gauss-Seidel") == 0)
  {
    computeRHSkv(g,s,l2norm);
    gaussSeidel(g,s,s->cflnum,dt);
  }
  else if (strcmp(stepType,"line-Gauss-Seidel") == 0)
  {

    if (g->visc) 
      computeRHSkv(g,s,l2norm);
    else
      computeRHSk(g,s,l2norm);

    lineGaussSeidel(g,s,s->cflnum,dt);
  }
  istep++;
}
// ===================================================
// Methods
// ===================================================
Real
OneDFSIFunctionSolverDefinedWindkessel3::operator() ( const Real& time, const Real& timeStep )
{
    UInt W_outID;
    Real W_out;

    switch ( M_bcType )
    {
        case OneDFSI::W1:
            W_outID = 1;
            W_out = computeRHS ( timeStep );
            break;
        case OneDFSI::W2:
            W_outID = 0;
            W_out = computeRHS ( timeStep );
            break;
        default:
            std::cout << "Warning: bcType \"" << M_bcType  << "\"not available!" << std::endl;
            break;
    }

    Real A ( M_bcU[0] );
    Real Q ( M_bcU[1] );

    if ( M_absorbing )
    {
        Real b1 ( M_fluxPtr->physics()->dPdW ( A, Q, 0, M_bcNode ) ); // dP / dW1 - Missing W_outID ???
        Real b2 ( A / 2 ); // dQ / dW1
        M_resistance1 = b1 / b2;
    }

    //  Trapezoidal rule for given integral
    //
    //  \int_0^t ( pv/(R2*C) + (R1+R2)/(R2*C) Q(s) + R1 dQ(s)/ds ) exp( s / (R2*C) ) ds
    //
    //  this gives: \int_0^t(n+1) = \int_0^t(n) + \int_t(n)^t(n+1)
    //
    //  \int_0^t(n) is stored from previous time step
    //  \int_t(n)^t(n+1) f(s) exp( a * s ) ds =
    //       =  dt/2 * ( f(t(n+1)) exp( a * t(n+1) ) + f(t(n)) exp( a * t(n) ) ) + O( dt^2 )
    //       =  dt/2 * [ exp(a*t(n)) * ( f(t(n+1))*exp(a*dt) + f(t(n)) ) ] + O( dt^2 )
    Real a        ( 1 / ( M_compliance * M_resistance2 ) );
    Real dQdt     ( ( Q - M_Q_tn ) / timeStep );
    Real F        ( a * M_venousPressure + a * (M_resistance1 + M_resistance2) * Q + M_resistance1 * dQdt );
    Real Fn       ( a * M_venousPressure + a * (M_resistance1 + M_resistance2) * M_Q_tn + M_resistance1 * M_dQdt_tn );
    Real EXP      ( std::exp ( a * time     ) );
    Real EXPdt    ( std::exp ( a * timeStep ) );
    Real integral ( M_integral_tn + ( timeStep / 2 ) * ( EXP * ( F * EXPdt + Fn ) ) );

    // Compute the solution of circuital ODE
    // P(t) = P(0) + [ \int_0^t ( pv/(R2*C) + (R1+R2)/(R2*C) Q(s)
    //                 + R1 dQ(s)/ds ) exp( s / (R2*C) ) ds ] * exp( - t / (R2*C) )
    Real P        ( M_P0 + integral / EXP );

    // Update variable for the next time step
    M_integral_tn = integral;
    M_dQdt_tn     = dQdt;
    M_Q_tn        = Q;

    // Remove this call to fromPToW it is not compatible with viscoelasticity!
    return  M_fluxPtr->physics()->fromPToW ( P, W_out, W_outID, M_bcNode ); // W_in
}
Esempio n. 5
0
void ImplicitStepper::solveNonLinear()
{
    StrandDynamics& dynamics = m_strand.dynamics() ;

    Scalar minErr = 1.e99, prevErr = 1.e99;
    m_newtonIter = 0;

    JacobianMatrixType bestLHS;
    VecXx bestRhs, prevRhs;

    Scalar alpha = 0.5;          // Current step length
    const Scalar minAlpha = 0.1; // Minimum step length

    bool foundOneSPD = false;
    m_strand.requireExactJacobian( false );

    // Newton loop -- try to zero-out m_rhs
    for( m_newtonIter = 0; m_newtonIter < m_params.m_maxNewtonIterations; ++m_newtonIter )
    {     
        dynamics.setDisplacements( m_dt * m_futureVelocities );

        prevRhs = m_rhs;
        computeRHS();

        if( m_newtonIter )
        {
            VecXx residual = m_rhs;

            dynamics.getScriptingController()->fixRHS( residual );
            const Scalar err = residual.squaredNorm() / residual.size();

            if( err < minErr || ( !foundOneSPD && !m_linearSolver.notSPD() ) )
            {
                foundOneSPD = !m_linearSolver.notSPD();
                minErr = err;

                if( isSmall( err ) || ( m_newtonIter > 3 && minErr < 1.e-6 ) )
                {
                    m_rhs = prevRhs;
                    break;
                }

                bestLHS = Lhs();
                bestRhs = prevRhs;
            }

            // Decrease or increase the step length based on current convergence
            if( err < prevErr ){
                alpha = std::min( 1.0, 1.5 * alpha );
            }
            else{
                alpha = std::max( minAlpha, 0.5 * alpha );
            }

            prevErr = err;
        }

        computeLHS();

        m_rhs = m_rhs * alpha;

        Lhs().multiply( m_rhs, 1., m_futureVelocities );
        dynamics.getScriptingController()->fixLHSAndRHS( Lhs(), m_rhs, m_dt );
        
        m_linearSolver.store( Lhs() );
        m_notSPD = m_linearSolver.notSPD();
        m_linearSolver.solve( m_futureVelocities, m_rhs );
    }

    // If the non-linear solve failed, returns to the the least problematic step
    if( m_newtonIter == m_params.m_maxNewtonIterations )
    {
        m_rhs = bestRhs;
        Lhs() = bestLHS;

        m_linearSolver.store( Lhs() );
        m_linearSolver.solve( m_futureVelocities, rhs() );
        m_notSPD = m_linearSolver.notSPD();
    }

    m_usedNonlinearSolver = true;
}
Esempio n. 6
0
void stepSolution(char *stepType,GRID *g,SOLN *s,double dt,double *l2norm, double *linfnorm, int myid)
{
 double     coef;
 static int istep=0;
 int i,k,l;
 int nsubiter=20;
 double CFL;

 CFL=g->CFL;

 if (strcmp(stepType,"euler")==0) 
 {
   communication(g,s,myid);
   if(g->visc)
   {
     computeRHSv(g,s,l2norm,linfnorm,myid);
   }
   else
   {
     computeRHS(g,s,l2norm,linfnorm,myid);
   }
   coef=1.0;
   updateSoln(s->q,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
  }
 else if (strcmp(stepType,"rk3") == 0){
   
   /* RK step 1 */
   communication(g,s,myid);
   computeRHS(g,s,l2norm,linfnorm,myid);
   coef=0.25;
   updateSoln(s->q,s->qt,s->r,s->sigma,dt,CFL,coef,g->ncells);
   coef=8.0/15;
   updateSoln(s->q,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
   
   /* RK step 2 */
   communication(g,s,myid);
   computeRHS(g,s,l2norm,linfnorm,myid);
   coef=5.0/12;
   updateSoln(s->qt,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
   
   /* RK step 3 */
   communication(g,s,myid);
   computeRHS(g,s,l2norm,linfnorm,myid);
   coef=3.0/4.0;
   updateSoln(s->qt,s->q,s->r,s->sigma,dt,CFL,coef,g->ncells);
 }
 else if (strcmp(stepType,"ADI")==0){
   // communication
   communication(g,s,myid);
   computeRHSk(g,s,l2norm,linfnorm,myid);
   ADI(g,s,s->cflnum,dt,myid);
 }
 else if (strcmp(stepType,"DADI")==0){
   // communication
   communication(g,s,myid);
   
   computeRHSk(g,s,l2norm,linfnorm,myid);
   DADI(g,s,s->cflnum,dt,myid);
 }
 else if (strcmp(stepType,"Gauss-Seidel") == 0) {
   // communication
   communication(g,s,myid);

   computeRHSkv(g,s,l2norm,myid);
   gaussSeidel(g,s,s->cflnum,dt,myid);
  }
 else if (strcmp(stepType,"line-Gauss-Seidel") == 0) {
   // communication
   communication(g,s,myid);
   if (g->visc) 
     {
       computeRHSkv(g,s,l2norm,myid);
     }
   else
     {       
       computeRHSk(g,s,l2norm,linfnorm,myid);
     }
   lineGaussSeidel(g,s,s->cflnum,dt,myid);
  }
 istep++;
}
Esempio n. 7
0
// ##################################################################
//
// step solution
//
// ##################################################################
void SOLVER::stepSolution(void)
{
   double coef;

   //
   // Euler explicit
   // 
   if (strcmp(stepType,"euler") == 0 )
   {
      if (sb->visc) 
      {
         cout << "Not yet implemented. exit.\n";
         exit(1);
         // computeRHSv;
      }
      else
         computeRHS("explicit");

      coef = 1.;
      updateSolution(sb->q,sb->q,coef);
   }
   //
   // Runge - Kutta 3
   //
   else if (strcmp(stepType,"rk3") == 0 )
   {
      // RK step 1 
      computeRHS("explicit");
      coef=0.25;
      updateSolution(sb->q,sb->qt,coef);
      coef=8.0/15;
      updateSolution(sb->q,sb->q,coef);

      // RK step 2 
      computeRHS("explicit");
      coef=5.0/12;
      updateSolution(sb->qt,sb->q,coef);

      // RK step 3 
      computeRHS("explicit");
      coef=3.0/4.0;
      updateSolution(sb->qt,sb->q,coef);
   }
   //
   // ADI ( Alternating Direction Implicit)
   //
   else if (strcmp(stepType,"ADI")==0)
   {
      // if(sb->idual==0)
      // {
         computeRHS("implicit");
         ADI();
      // }
      // else //dual time stepping
      // {
      //    printf("Error. Dual Time stepping not yet implemented.\n");
      //    exit(1);
      //    // for (i = 0; i < NQ*mb->nCell; i++) sb->pq[i] = sb->q[i];

      //    // for(k = 0; k < sb->ndual; k++)
      //    // {
      //    //    DualcomputeRHSk(g,s,l2norm,s->cflnum);
      //    //    DualADI(g,s,s->cflnum,dt);
      //    // }

      //    // for (i=0;i<NVAR*g->ncells;i++) s->q[i] = s->pq[i];
      // }
   }
}