Пример #1
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() );
}
Пример #2
0
VecXx& ImplicitStepper::impulse_rhs()
{
    StrandDynamics& dynamics = m_strand.dynamics();
    m_impulseRhs = m_futureVelocities;
    dynamics.multiplyByMassMatrix( m_impulseRhs );
  
    computeLHS();
    dynamics.getScriptingController()->fixLHSAndRHS( Lhs(), m_impulseRhs, m_dt );
    m_linearSolver.store( Lhs() );

    return m_impulseRhs;
}
Пример #3
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;
}
Пример #4
0
static void AssignmentStatement(void)
{
    Int32 type,count;
	SymPtr sym,clas_init=NULL;
	SymPtr parents[16];

	sym = Lhs();

	if( sym==NULL )
	{
		return;
	}
    
    CheckClassMember(sym);

	SkipToken(tEQUALS);

	if(sym->flags&SYM_DEFINED)
	{
		compileError("cannot reassign constant");
		return;
	}
	else if(sym->flags&SYM_CONSTANT)
	{
		sym->flags |= SYM_DEFINED;
	}	

    /* CheckClassMember(sym); */
	
    new_class=NULL;
	type=Expr();
	
	sym->object.type = type;
		
	switch(sym->kind)
	{
	case LOCAL_KIND:
		vm_genI(op_setlocal,sym->num);
		break;
	
	case GLOBAL_KIND:
		vm_genI(op_setglobal,sym->num);
		break;

	case FIELD_KIND:
		vm_genI(op_setfield,sym->num);
		break;

	default: 
		compileError("invalid assignment");
		break;
	}

	if( type==CLASS_TYPE && new_class != NULL )
	{
        sym->clas = new_class;
  		sym->super = new_class->super;
    	sym->locals = new_class->locals;

		/* First build a list of all super classes */
		count=0;
		clas_init=sym;
		while( clas_init!=NULL )
		{
			parents[count++] = clas_init;
			clas_init = clas_init->super;
		}
		
		/* Now call all constructors in reverse order */
		count--;
		while( count>=0 )
		{
			clas_init = SymFindLocal(NEW,parents[count]);
			FunctionCall(clas_init,sym);
			vm_gen0(op_pop);
			count--;
		}

        /* call user defined constructor */
		clas_init=SymFindLocal("init",sym);
		if( clas_init!=NULL )
		{
    		if( (Token==tLPAREN && clas_init->nargs!=0) ||
                (Token!=tLPAREN && clas_init->nargs==0) )
		    {
				FunctionCall(clas_init,sym);
				vm_gen0(op_pop);
			}
		}
	}
}