Exemplo n.º 1
0
void
FSIMonolithicGE::evalResidual( vector_Type&       res,
                            const vector_Type& disp,
                            const UInt          iter )
{
    // disp here is the current solution guess (u,p,ds)
    // disp is already "extrapolated", the main is doing it.

    if (iter==0)
    {

        // Solve HE
        this->iterateMesh(disp);

        // Update displacement

        M_ALETimeAdvance->updateRHSFirstDerivative(M_data->dataFluid()->dataTime()->timeStep());

        vector_Type meshDispRepeated( M_meshMotion->disp(), Repeated );
        this->moveMesh(meshDispRepeated);

        //here should use extrapolationFirstDerivative instead of velocity
        vector_Type meshVelocityRepeated ( this->M_ALETimeAdvance->nextFirstDerivative(  M_meshMotion->disp() ), Repeated );
        vector_Type interpolatedMeshVelocity(this->M_uFESpace->map());

        interpolateVelocity( meshVelocityRepeated, interpolatedMeshVelocity );
        // maybe we should use disp here too...
        M_fluidTimeAdvance->extrapolation(*M_beta);
        *M_beta -= interpolatedMeshVelocity; // convective term, u^* - w^*

        // in MonolithicGI here it used M_uk, which comes from disp
        assembleSolidBlock(iter, disp);
        assembleFluidBlock(iter, disp);
        *M_rhsFull = *M_rhs;

        applyBoundaryConditions();
    }
    super_Type::evalResidual( disp,  M_rhsFull, res, M_diagonalScale);
}
Exemplo n.º 2
0
void FSIExactJacobian::eval (const vector_Type& _disp,
                             const UInt          iter)
{
    LifeChrono chronoFluid, chronoSolid, chronoInterface;

    bool recomputeMatrices ( iter == 0 || ( !this->M_data->dataFluid()->isSemiImplicit() &&
                                            ( M_data->updateEvery() > 0 &&
                                              (iter % M_data->updateEvery() == 0) ) ) );

    if (iter == 0)
    {
        if (isFluid() )
        {
            this->M_fluid->resetPreconditioner();
        }
        //this->M_solid->resetPrec();
    }


    this->setLambdaFluid (_disp);


    vector_Type sigmaFluidUnique (this->sigmaFluid(), Unique);

    M_epetraWorldComm->Barrier();
    chronoFluid.start();

    if (isFluid() )
    {
        M_meshMotion->iterate (*M_BCh_mesh);
        // M_meshMotion->updateDispDiff();


        // copying displacement to a repeated indeces displacement, otherwise the mesh wont know
        // the value of the displacement for some points


        if ( iter == 0 || !this->M_data->dataFluid()->isSemiImplicit() )
        {
            *M_beta *= 0.;

            if ( iter == 0 )
            {
                M_ALETimeAdvance->updateRHSFirstDerivative (M_data->dataFluid()->dataTime()->timeStep() );
                M_ALETimeAdvance->shiftRight (M_meshMotion->disp() );
                M_ALETimeAdvance->extrapolation (M_meshMotion->disp() ); //closer initial solution
            }
            else
            {
                M_ALETimeAdvance->setSolution (M_meshMotion->disp() );
            }

            vector_Type meshDispRepeated ( M_meshMotion->disp(), Repeated );
            this->moveMesh (meshDispRepeated);
            vector_Type vel ( this->M_ALETimeAdvance->firstDerivative( ) );
            transferMeshMotionOnFluid ( vel, veloFluidMesh() );
            M_fluidTimeAdvance->extrapolation (*M_beta); //explicit
            *M_beta -= veloFluidMesh();//implicit


            //the conservative formulation as it is now is of order 1. To have higher order (TODO) we need to store the mass matrices computed at the previous time steps.
            if (M_data->dataFluid()->conservativeFormulation() )
                //*M_rhs = M_fluid->matrixMass()*M_fluidTimeAdvance->rhsContributionFirstDerivative();
            {
                *M_rhs = M_fluidMassTimeAdvance->rhsContributionFirstDerivative();
            }


            if (recomputeMatrices)
            {
                double alpha = M_fluidTimeAdvance->coefficientFirstDerivative (0) / M_data->dataFluid()->dataTime()->timeStep();
                this->M_fluid->updateSystem ( alpha, *M_beta, *M_rhs );
            }
            else
            {
                this->M_fluid->updateRightHandSide ( *M_rhs );
            }
            if (!M_data->dataFluid()->conservativeFormulation() )
            {
                *M_rhs = M_fluid->matrixMass() * M_fluidTimeAdvance->rhsContributionFirstDerivative();
                this->M_fluid->updateRightHandSide ( *M_rhs );
            }
        }

        this->M_fluid->iterate ( *M_BCh_u );

        this->transferFluidOnInterface (this->M_fluid->residual(), sigmaFluidUnique);
    }

    M_epetraWorldComm->Barrier();
    chronoFluid.stop();
    this->displayer().leaderPrintMax ("      Fluid solution total time:               ", chronoFluid.diff() );

    if ( false && this->isFluid() )
    {
        vector_Type vel  (this->fluid().velocityFESpace().map() );
        vector_Type press (this->fluid().pressureFESpace().map() );

        vel.subset (*this->M_fluid->solution() );
        press.subset (*this->M_fluid->solution(), this->fluid().velocityFESpace().dim() *this->fluid().pressureFESpace().fieldDim() );

        std::cout << "norm_inf( vel ) " << vel.normInf() << std::endl;
        std::cout << "norm_inf( press ) " << press.normInf() << std::endl;

        //this->M_fluid->postProcess();
    }

    chronoInterface.start();

    this->setSigmaFluid ( sigmaFluidUnique );
    this->setSigmaSolid ( sigmaFluidUnique );



    vector_Type lambdaSolidUnique   (this->lambdaSolid(),    Unique);
    vector_Type lambdaDotSolidUnique (this->lambdaDotSolid(), Unique);
    vector_Type sigmaSolidUnique    (this->sigmaSolid(),     Unique);

    chronoInterface.stop();
    M_epetraWorldComm->Barrier();
    chronoSolid.start();

    if (this->isSolid() )
    {
        this->M_solid->iterate ( M_BCh_d );
    }

    M_epetraWorldComm->Barrier();
    chronoSolid.stop();
    this->displayer().leaderPrintMax ("      Solid solution total time:               ", chronoSolid.diff() );

    chronoInterface.start();

    if (this->isSolid() )
    {
        this->transferSolidOnInterface (this->M_solid->displacement(),     lambdaSolidUnique);
        this->transferSolidOnInterface ( this->M_solidTimeAdvance->firstDerivative ( this->M_solid->displacement() ), lambdaDotSolidUnique );
        this->transferSolidOnInterface (this->M_solid->residual(), sigmaSolidUnique);
    }

    this->setLambdaSolid (    lambdaSolidUnique);
    this->setLambdaDotSolid ( lambdaDotSolidUnique);
    this->setSigmaSolid (     sigmaSolidUnique);

    chronoInterface.stop();
    this->displayer().leaderPrintMax ("      Interface transfer total time:           ", chronoInterface.diffCumul() );


    // possibly unsafe when using more cpus, since both has repeated maps

    this->displayer().leaderPrint ("      Norm(disp     )    =                     ", _disp.normInf(), "\n");
    this->displayer().leaderPrint ("      Norm(dispNew  )    =                     " , this->lambdaSolid().normInf(), "\n" );
    this->displayer().leaderPrint ("      Norm(velo     )    =                     " , this->lambdaDotSolid().normInf(), "\n" );
    this->displayer().leaderPrint ("      Max Residual Fluid =                     " , this->sigmaFluid().normInf(), "\n" );
    this->displayer().leaderPrint ("      Max Residual Solid =                     " , this->sigmaSolid().normInf(), "\n" );

    if ( this->isFluid() )
    {
        this->displayer().leaderPrint ("      Max ResidualF      =                     " , M_fluid->residual().normInf(), "\n" );
    }
    if ( this->isSolid() )
    {
        this->displayer().leaderPrint ("      NL2 Diplacement S. =                     " , M_solid->displacement().norm2(), "\n" );
        this->displayer().leaderPrint ("      Max Residual Solid =                     " , M_solid->residual().normInf(), "\n" );
    }
}