// 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; }
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)); } } } }
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" ); } }