Пример #1
0
// checks if there is a platform for placing something somewhere
// check in a square that there is _AIR from y and above
// and check that there is solid ground at y-1
bool coretest(int x, int y, int z, int ground_rad, int air_rad, int height)
{
	int maxrad = ground_rad * ground_rad;
	for (int dx = -ground_rad; dx <= ground_rad; dx++)
	for (int dz = -ground_rad; dz <= ground_rad; dz++)
	{
		if (dx*dx + dz*dz <= maxrad)
		{
			// ground test: exit when AIR
			block_t block = getblock(x + dx, y-1, z + dz);
			if (block <= air_end || block >= halfblock_start) return false;
		}
	}
	
	for (int dy = 0; dy < height; dy++)
	{
		maxrad = air_rad * air_rad;
		for (int dx = -air_rad; dx <= air_rad; dx++)
		for (int dz = -air_rad; dz <= air_rad; dz++)
		{
			if (dx*dx + dz*dz <= maxrad)
			{
				// air test: exit when not AIR or fluid
				block_t block = getblock(x + dx, y + dy, z + dz);
				if (isSolid(block) || isFluid(block)) return false;
			}
		}
	}
	return true;
}
Пример #2
0
void FluidSDF::_sweep(int i0, int i1, int j0, int j1)
{
    const int di = i0 < i1 ? 1 : -1;
    const int dj = j0 < j1 ? 1 : -1;
    for (int i = i0; i != i1; i+= di) {
        for (int j = j0; j != j1; j+= dj) {
            if (!isFluid(i,j)) {
                _solveEikonal(_phi(i - di,j), _phi(i,j - dj), _phi(i,j));
            }
        }
    }
}
Пример #3
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" );
    }
}