Пример #1
0
        /// Performs the static analysis,
        /// doing a linear solve.

        public override void StaticAnalysis()
        {
            ChIntegrableIIorder mintegrable = (ChIntegrableIIorder)this.integrable;

            // setup main vectors
            mintegrable.StateSetup(ref X, ref V, ref A);

            ChStateDelta             Dx = new ChStateDelta();
            ChVectorDynamic <double> R  = new ChVectorDynamic <double>();
            ChVectorDynamic <double> Qc = new ChVectorDynamic <double>();
            double T = 0;

            // setup auxiliary vectors
            Dx.Reset(mintegrable.GetNcoords_v(), GetIntegrable());
            R.Reset(mintegrable.GetNcoords_v());
            Qc.Reset(mintegrable.GetNconstr());
            L.Reset(mintegrable.GetNconstr());

            mintegrable.StateGather(ref X, ref V, ref T);  // state <- system

            // Set V speed to zero
            V.matrix.FillElem(0);
            mintegrable.StateScatter(X, V, T);  // state -> system

            // Solve:
            //
            // [-dF/dx     Cq' ] [ dx  ] = [ f]
            // [ Cq        0   ] [  l  ] = [ C]

            mintegrable.LoadResidual_F(ref R, 1.0);
            mintegrable.LoadConstraint_C(ref Qc, 1.0);

            mintegrable.StateSolveCorrection(
                ref Dx, ref L, R, Qc,
                0,        // factor for  M
                0,        // factor for  dF/dv
                -1.0,     // factor for  dF/dx (the stiffness matrix)
                X, V, T,  // not needed here
                false,    // do not StateScatter update to Xnew Vnew T+dt before computing correction
                true      // force a call to the solver's Setup() function
                );

            X += Dx;

            mintegrable.StateScatter(X, V, T);    // state -> system
            mintegrable.StateScatterReactions(L); // -> system auxiliary data
        }
Пример #2
0
        /// Performs the static analysis,
        /// doing a linear solve.

        public override void StaticAnalysis()
        {
            ChIntegrableIIorder mintegrable = (ChIntegrableIIorder)this.integrable;

            // setup main vectors
            mintegrable.StateSetup(ref X, ref V, ref A);

            ChState                  Xnew = new ChState();
            ChStateDelta             Dx   = new ChStateDelta();
            ChVectorDynamic <double> R    = new ChVectorDynamic <double>();
            ChVectorDynamic <double> Qc   = new ChVectorDynamic <double>();
            double T = 0;

            // setup auxiliary vectors
            Dx.Reset(mintegrable.GetNcoords_v(), GetIntegrable());
            Xnew.Reset(mintegrable.GetNcoords_x(), mintegrable);
            R.Reset(mintegrable.GetNcoords_v());
            Qc.Reset(mintegrable.GetNconstr());
            L.Reset(mintegrable.GetNconstr());

            mintegrable.StateGather(ref X, ref V, ref T);  // state <- system

            // Set speed to zero
            V.matrix.FillElem(0);

            // Extrapolate a prediction as warm start
            Xnew = X;

            // use Newton Raphson iteration to solve implicit Euler for v_new
            //
            // [ - dF/dx    Cq' ] [ Dx  ] = [ f ]
            // [ Cq         0   ] [ L   ] = [ C ]

            for (int i = 0; i < this.GetMaxiters(); ++i)
            {
                mintegrable.StateScatter(Xnew, V, T);  // state -> system
                R.Reset();
                Qc.Reset();
                mintegrable.LoadResidual_F(ref R, 1.0);
                mintegrable.LoadConstraint_C(ref Qc, 1.0);

                double cfactor = ChMaths.ChMin(1.0, ((double)(i + 2) / (double)(incremental_steps + 1)));
                R  *= cfactor;
                Qc *= cfactor;

                //	GetLog()<< "Non-linear statics iteration=" << i << "  |R|=" << R.NormInf() << "  |Qc|=" << Qc.NormInf()
                //<< "\n";
                if ((R.matrix.NormInf() < this.GetTolerance()) && (Qc.matrix.NormInf() < this.GetTolerance()))
                {
                    break;
                }

                mintegrable.StateSolveCorrection(
                    ref Dx, ref L, R, Qc,
                    0,           // factor for  M
                    0,           // factor for  dF/dv
                    -1.0,        // factor for  dF/dx (the stiffness matrix)
                    Xnew, V, T,  // not needed here
                    false,       // do not StateScatter update to Xnew Vnew T+dt before computing correction
                    true         // force a call to the solver's Setup() function
                    );

                Xnew += Dx;
            }

            X = Xnew;

            mintegrable.StateScatter(X, V, T);    // state -> system
            mintegrable.StateScatterReactions(L); // -> system auxiliary data
        }
Пример #3
0
        /// Performs an integration timestep
        public override void Advance(double dt  //< timestep to advance
                                     )
        {
            // downcast
            ChIntegrableIIorder mintegrable = (ChIntegrableIIorder)this.integrable;

            // setup main vectors
            mintegrable.StateSetup(ref X, ref V, ref A);

            // setup auxiliary vectors
            Dl.Reset(mintegrable.GetNconstr());
            R.Reset(mintegrable.GetNcoords_v());
            Qc.Reset(mintegrable.GetNconstr());
            L.Reset(mintegrable.GetNconstr());

            mintegrable.StateGather(ref X, ref V, ref T); // state <- system
            mintegrable.StateGatherReactions(ref L);      // state <- system (may be needed for warm starting StateSolveCorrection)

            L *= dt;                                      // because reactions = forces, here L = impulses

            Vold = V;

            // solve only 1st NR step, using v_new = 0, so  Dv = v_new , therefore
            //
            // [ M - dt*dF/dv - dt^2*dF/dx    Cq' ] [ Dv     ] = [ M*(v_old - v_new) + dt*f]
            // [ Cq                           0   ] [ -dt*Dl ] = [ -C/dt - Ct ]
            //
            // becomes the Anitescu/Trinkle timestepper:
            //
            // [ M - dt*dF/dv - dt^2*dF/dx    Cq' ] [ v_new  ] = [ M*(v_old) + dt*f]
            // [ Cq                           0   ] [ -dt*l  ] = [ -C/dt - Ct ]

            mintegrable.LoadResidual_F(ref R, dt);
            mintegrable.LoadResidual_Mv(ref R, V, 1.0);
            mintegrable.LoadConstraint_C(ref Qc, 1.0 / dt, Qc_do_clamp, Qc_clamping);
            mintegrable.LoadConstraint_Ct(ref Qc, 1.0);

            // Can't shave anymore off this, Solver() is the only cpu drain.
            mintegrable.StateSolveCorrection(
                ref V, ref L, R, Qc,
                1.0,           // factor for  M
                -dt,           // factor for  dF/dv
                -dt * dt,      // factor for  dF/dx
                X, V, T + dt,  // not needed
                false,         // do not StateScatter update to Xnew Vnew T+dt before computing correction
                true           // force a call to the solver's Setup() function
                );


            L *= (1.0 / dt);  // Note it is not -(1.0/dt) because we assume StateSolveCorrection already flips sign of Dl

            mintegrable.StateScatterAcceleration(
                (V - Vold) * (1 / dt));  // . system auxiliary data (i.e acceleration as measure, fits DVI/MDI)


            X += V * dt;

            T += dt;

            mintegrable.StateScatter(X, V, T);     // state . system  // Big cpu drain
            mintegrable.StateScatterReactions(L);  // . system auxiliary data*/
        }
Пример #4
0
        /// Performs an integration timestep
        public override void Advance(double dt  //< timestep to advance
                                     )
        {
            // downcast
            ChIntegrableIIorder mintegrable = (ChIntegrableIIorder)this.integrable;

            // setup main vectors
            mintegrable.StateSetup(ref X, ref V, ref A);

            // setup auxiliary vectors
            Dl.Reset(mintegrable.GetNconstr());
            R.Reset(mintegrable.GetNcoords_v());
            Qc.Reset(mintegrable.GetNconstr());
            L.Reset(mintegrable.GetNconstr());

            mintegrable.StateGather(ref X, ref V, ref T);  // state <- system

            Vold = V;

            // 1
            // Do a  Anitescu/Trinkle timestepper (it could be without the C/dt correction):
            //
            // [ M - dt*dF/dv - dt^2*dF/dx    Cq' ] [ v_new  ] = [ M*(v_old) + dt*f]
            // [ Cq                           0   ] [ -dt*l  ] = [ -Ct ]

            mintegrable.LoadResidual_F(ref R, dt);
            mintegrable.LoadResidual_Mv(ref R, V, 1.0);
            mintegrable.LoadConstraint_C(ref Qc, 1.0 / dt, Qc_do_clamp, 0); // may be avoided
            mintegrable.LoadConstraint_Ct(ref Qc, 1.0);

            mintegrable.StateSolveCorrection(
                ref V, ref L, R, Qc,
                1.0,           // factor for  M
                -dt,           // factor for  dF/dv
                -dt * dt,      // factor for  dF/dx
                X, V, T + dt,  // not needed
                false,         // do not StateScatter update to Xnew Vnew T+dt before computing correction
                true           // force a call to the solver's Setup() function
                );

            L *= (1.0 / dt);  // Note it is not -(1.0/dt) because we assume StateSolveCorrection already flips sign of Dl

            mintegrable.StateScatterAcceleration(
                (V - Vold) * (1 / dt));  // . system auxiliary data (i.e acceleration as measure, fits DVI/MDI)

            X += V * dt;

            T += dt;

            mintegrable.StateScatter(X, V, T);     // state . system
            mintegrable.StateScatterReactions(L);  // . system auxiliary data

            // 2
            // Do the position stabilization (single NR step on constraints, with mass matrix as metric)

            Dl.Reset(mintegrable.GetNconstr());
            R.Reset(mintegrable.GetNcoords_v());
            Qc.Reset(mintegrable.GetNconstr());
            L.Reset(mintegrable.GetNconstr());
            Vold.Reset(mintegrable.GetNcoords_v(), V.GetIntegrable());

            //
            // [ M       Cq' ] [ dpos ] = [  0 ]
            // [ Cq       0  ] [ l    ] = [ -C ]

            mintegrable.LoadConstraint_C(ref Qc, 1.0, false, 0);

            mintegrable.StateSolveCorrection(
                ref Vold, ref L, R, Qc,
                1.0,      // factor for  M
                0,        // factor for  dF/dv
                0,        // factor for  dF/dx
                X, V, T,  // not needed
                false,    // do not StateScatter update to Xnew Vnew T+dt before computing correction
                true      // force a call to the solver's Setup() function
                );

            X += Vold;                         // here we used 'Vold' as 'dpos' to recycle Vold and avoid allocating a new vector dpos

            mintegrable.StateScatter(X, V, T); // state . system
        }
Пример #5
0
        /// Perform the assembly analysis.
        /// Assembly is performed by satisfying constraints at a position, velocity, and acceleration levels.
        /// Assembly at position level involves solving a non-linear problem. Assembly at velocity level is
        /// performed by taking a small integration step. Consistent accelerations are obtained through
        /// finite differencing.
        public void AssemblyAnalysis(int action, double dt = 1e-7)
        {
            ChVectorDynamic <double> R  = new ChVectorDynamic <double>();
            ChVectorDynamic <double> Qc = new ChVectorDynamic <double>();
            double T = 0;

            // Set up main vectors
            integrable.StateSetup(ref X, ref V, ref A);

            if (action != 0 && AssemblyLevel.Enum.POSITION != 0)
            {
                ChStateDelta Dx = new ChStateDelta();

                for (int m_iter = 0; m_iter < max_assembly_iters; m_iter++)
                {
                    // Set up auxiliary vectors
                    Dx.Reset(integrable.GetNcoords_v(), GetIntegrable());
                    R.Reset(integrable.GetNcoords_v());
                    Qc.Reset(integrable.GetNconstr());
                    L.Reset(integrable.GetNconstr());

                    integrable.StateGather(ref X, ref V, ref T);  // state <- system

                    // Solve:
                    //
                    // [M          Cq' ] [ dx  ] = [ 0]
                    // [ Cq        0   ] [  l  ] = [ C]

                    integrable.LoadConstraint_C(ref Qc, 1.0);

                    integrable.StateSolveCorrection(
                        ref Dx, ref L, R, Qc,
                        1.0,      // factor for  M
                        0,        // factor for  dF/dv
                        0,        // factor for  dF/dx (the stiffness matrix)
                        X, V, T,  // not needed
                        false,    // do not StateScatter update to Xnew Vnew T+dt before computing correction
                        true      // force a call to the solver's Setup function
                        );

                    X += Dx;

                    integrable.StateScatter(X, V, T);  // state -> system
                }
            }

            if ((action != 0 & AssemblyLevel.Enum.VELOCITY != 0) || (action != 0 & AssemblyLevel.Enum.ACCELERATION != 0))
            {
                ChStateDelta Vold = new ChStateDelta();

                // setup auxiliary vectors
                Vold.Reset(integrable.GetNcoords_v(), GetIntegrable());
                R.Reset(integrable.GetNcoords_v());
                Qc.Reset(integrable.GetNconstr());
                L.Reset(integrable.GetNconstr());

                integrable.StateGather(ref X, ref V, ref T);  // state <- system

                Vold = V;

                // Perform a linearized semi-implicit Euler integration step
                //
                // [ M - dt*dF/dv - dt^2*dF/dx    Cq' ] [ v_new  ] = [ M*(v_old) + dt*f]
                // [ Cq                           0   ] [ -dt*l  ] = [ C/dt + Ct ]

                integrable.LoadResidual_F(ref R, dt);
                integrable.LoadResidual_Mv(ref R, V, 1.0);
                integrable.LoadConstraint_C(ref Qc, 1.0 / dt, false);
                integrable.LoadConstraint_Ct(ref Qc, 1.0);

                integrable.StateSolveCorrection(
                    ref V, ref L, R, Qc,
                    1.0,           // factor for  M
                    -dt,           // factor for  dF/dv
                    -dt * dt,      // factor for  dF/dx
                    X, V, T + dt,  // not needed
                    false,         // do not StateScatter update to Xnew Vnew T+dt before computing correction
                    true           // force a call to the solver's Setup() function
                    );

                integrable.StateScatter(X, V, T); // state -> system

                L *= (1.0 / dt);                  // Note it is not -(1.0/dt) because we assume StateSolveCorrection already flips sign of L

                if (action != 0 & AssemblyLevel.Enum.ACCELERATION != 0)
                {
                    integrable.StateScatterAcceleration(
                        (V - Vold) * (1 / dt));          // -> system auxiliary data (i.e acceleration as measure, fits DVI/MDI)

                    integrable.StateScatterReactions(L); // -> system auxiliary data
                }
            }
        }