int main() { int nbComputations = 6; int nbNodes = 5; #pragma omp parallel for collapse(2), schedule(dynamic,1) for ( int iNodes = 0; iNodes < nbNodes; iNodes++ ) { for ( int iComputation = 0; iComputation < nbComputations; iComputation++ ) { unsigned int nbNodes = iNodes + 1; unsigned int nbTimeSteps = std::pow( 2, iComputation ); std::shared_ptr<sdc::TimeIntegrationScheme> timeIntegrationScheme; std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> fluid; std::shared_ptr<tubeflow::SDCTubeFlowBDFLinearizedSolidSolver> solid; std::shared_ptr<MultiLevelFsiSolver> fsi; { scalar r0 = 0.2; scalar a0 = M_PI * r0 * r0; scalar u0 = 0.1; scalar p0 = 0; scalar L = 1; scalar T = 1; scalar dt = T / nbTimeSteps; scalar rho_f = 1.225; scalar rho_s = 1.225; scalar E0 = 490; scalar G = 490; scalar h = 1.0e-3; scalar nu = 0.5; scalar cmk = std::sqrt( E0 * h / (2 * rho_f * r0) ); int N = 250; bool parallel = false; int extrapolation = 0; int maxIter = 100; scalar initialRelaxation = 1.0e-3; int maxUsedIterations = 50; int nbReuse = 0; scalar tol = 1.0e-5; scalar absoluteTol = 1.0e-13; scalar singularityLimit = 1.0e-13; int reuseInformationStartingFromTimeIndex = 0; bool scaling = false; bool updateJacobian = false; scalar beta = 0.1; int timeOrder = 1; if ( nbNodes > 1 ) timeOrder = 2; fluid = std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> ( new tubeflow::SDCTubeFlowFluidSolver( a0, u0, p0, dt, cmk, N, L, T, rho_f ) ); solid = std::shared_ptr<tubeflow::SDCTubeFlowBDFLinearizedSolidSolver>( new tubeflow::SDCTubeFlowBDFLinearizedSolidSolver( N, nu, rho_s, h, L, dt, G, E0, r0, T, timeOrder ) ); shared_ptr<MultiLevelSolver> fluidSolver( new MultiLevelSolver( fluid, fluid, 0, 0 ) ); shared_ptr<MultiLevelSolver> solidSolver( new MultiLevelSolver( solid, fluid, 1, 0 ) ); std::shared_ptr< std::list<std::shared_ptr<ConvergenceMeasure> > > convergenceMeasures; convergenceMeasures = std::shared_ptr<std::list<std::shared_ptr<ConvergenceMeasure> > >( new std::list<std::shared_ptr<ConvergenceMeasure> > ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new ResidualRelativeConvergenceMeasure( 0, true, tol ) ) ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new AbsoluteConvergenceMeasure( 0, true, 0.1 * absoluteTol ) ) ); fsi = shared_ptr<MultiLevelFsiSolver> ( new MultiLevelFsiSolver( fluidSolver, solidSolver, convergenceMeasures, parallel, extrapolation ) ); shared_ptr<PostProcessing> postProcessing( new AndersonPostProcessing( fsi, maxIter, initialRelaxation, maxUsedIterations, nbReuse, singularityLimit, reuseInformationStartingFromTimeIndex, scaling, beta, updateJacobian ) ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcFluidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( fluid ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcSolidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( solid ); assert( sdcFluidSolver ); assert( sdcSolidSolver ); std::shared_ptr<fsi::SDCFsiSolver> fsiSolver( new fsi::SDCFsiSolver( sdcFluidSolver, sdcSolidSolver, postProcessing ) ); std::shared_ptr<fsi::quadrature::IQuadrature<scalar> > quadrature; quadrature = std::shared_ptr<fsi::quadrature::IQuadrature<scalar> >( new fsi::quadrature::Uniform<scalar>( nbNodes ) ); timeIntegrationScheme = std::shared_ptr<sdc::TimeIntegrationScheme> ( new sdc::SDC( fsiSolver, quadrature, absoluteTol, nbNodes, 50 ) ); } assert( timeIntegrationScheme ); assert( fluid ); assert( solid ); assert( fsi ); std::chrono::time_point<std::chrono::high_resolution_clock> start, end; start = std::chrono::high_resolution_clock::now(); timeIntegrationScheme->run(); end = std::chrono::high_resolution_clock::now(); std::chrono::duration<double> elapsed_seconds = end - start; std::string label = "IDC_BDF"; label += "_nbNodes_" + std::to_string( nbNodes ); label += "_nbTimeSteps_" + std::to_string( nbTimeSteps ); ofstream log_file( label + ".log" ); ofstream data_fluid_u( label + "_data_fluid_u.log" ); ofstream data_fluid_a( label + "_data_fluid_a.log" ); ofstream data_fluid_p( label + "_data_fluid_p.log" ); ofstream data_solid_u( label + "_data_solid_u.log" ); ofstream data_solid_r( label + "_data_solid_r.log" ); log_file << "label = " << label << std::endl; log_file << "nbNodes = " << nbNodes << std::endl; log_file << "nbTimeSteps = " << nbTimeSteps << std::endl; log_file << "nbIterations = " << fsi->nbIter << std::endl; log_file << "timing = " << elapsed_seconds.count() << std::endl; data_fluid_u << std::setprecision( 20 ) << fluid->u << std::endl; data_fluid_a << std::setprecision( 20 ) << fluid->a << std::endl; data_fluid_p << std::setprecision( 20 ) << fluid->p << std::endl; data_solid_u << std::setprecision( 20 ) << solid->u << std::endl; data_solid_r << std::setprecision( 20 ) << solid->r << std::endl; log_file.close(); data_fluid_u.close(); data_fluid_a.close(); data_fluid_p.close(); data_solid_u.close(); data_solid_r.close(); } } }
TEST( SDIRKFsiSolidTest, linearized ) { scalar r0 = 3.0e-3; scalar h = 3.0e-4; scalar L = 0.126; scalar rho_s = 1000; scalar E0 = 4.0e5; scalar G = 4.0e5; scalar nu = 0.5; scalar a0 = M_PI * r0 * r0; scalar u0 = 0.26; scalar p0 = 0; int N = 5; scalar T = 1; scalar rho_f = 1060; scalar E = 490; scalar cmk = std::sqrt( E * h / (2 * rho_f * r0) ); bool parallel = false; int extrapolation = 0; scalar tol = 1.0e-8; int maxIter = 50; scalar initialRelaxation = 1.0e-3; int maxUsedIterations = 50; int nbReuse = 0; scalar singularityLimit = 1.0e-13; int reuseInformationStartingFromTimeIndex = 0; bool scaling = false; scalar beta = 0.01; bool updateJacobian = false; int minIter = 5; int nbComputations = 3; std::deque<std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> > fluidSolvers; std::deque<std::shared_ptr<tubeflow::SDCTubeFlowLinearizedSolidSolver> > solidSolvers; std::deque<int> nbTimeStepsList; for ( int iComputation = 0; iComputation < nbComputations; iComputation++ ) { int nbTimeSteps = 120 * std::pow( 2, iComputation ); std::cout << "nbTimeSteps = " << nbTimeSteps << std::endl; scalar dt = T / nbTimeSteps; std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> fluid( new tubeflow::SDCTubeFlowFluidSolver( a0, u0, p0, dt, cmk, N, L, T, rho_f ) ); std::shared_ptr<tubeflow::SDCTubeFlowLinearizedSolidSolver> solid( new tubeflow::SDCTubeFlowLinearizedSolidSolver( N, nu, rho_s, h, L, dt, G, E0, r0, T ) ); shared_ptr<RBFFunctionInterface> rbfFunction; shared_ptr<RBFInterpolation> rbfInterpolator; shared_ptr<RBFCoarsening> rbfInterpToCouplingMesh; shared_ptr<RBFCoarsening> rbfInterpToMesh; rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> fluidSolver( new MultiLevelSolver( fluid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 0, 0 ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> solidSolver( new MultiLevelSolver( solid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 1, 0 ) ); std::shared_ptr< std::list<std::shared_ptr<ConvergenceMeasure> > > convergenceMeasures; convergenceMeasures = std::shared_ptr<std::list<std::shared_ptr<ConvergenceMeasure> > >( new std::list<std::shared_ptr<ConvergenceMeasure> >() ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new RelativeConvergenceMeasure( 0, true, tol ) ) ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new MinIterationConvergenceMeasure( 0, false, minIter ) ) ); shared_ptr<MultiLevelFsiSolver> fsi( new MultiLevelFsiSolver( fluidSolver, solidSolver, convergenceMeasures, parallel, extrapolation ) ); shared_ptr<PostProcessing> postProcessing( new AndersonPostProcessing( fsi, maxIter, initialRelaxation, maxUsedIterations, nbReuse, singularityLimit, reuseInformationStartingFromTimeIndex, scaling, beta, updateJacobian ) ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcFluidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( fluid ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcSolidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( solid ); assert( sdcFluidSolver ); assert( sdcSolidSolver ); std::shared_ptr<fsi::SDCFsiSolver> fsiSolver( new fsi::SDCFsiSolver( sdcFluidSolver, sdcSolidSolver, postProcessing, extrapolation ) ); std::shared_ptr<sdc::AdaptiveTimeStepper> adaptiveTimeStepper( new sdc::AdaptiveTimeStepper( false ) ); std::string method = "ESDIRK53PR"; std::shared_ptr<sdc::ESDIRK> esdirk( new sdc::ESDIRK( fsiSolver, method, adaptiveTimeStepper ) ); esdirk->run(); fluidSolvers.push_back( fluid ); solidSolvers.push_back( solid ); nbTimeStepsList.push_back( nbTimeSteps ); } std::cout << "solid" << std::endl; for ( int i = 0; i < 2; i++ ) { fsi::vector ref; if ( i == 0 ) ref = solidSolvers.back()->r; else ref = solidSolvers.back()->u; std::deque<scalar> errors; for ( int iComputation = 0; iComputation < nbComputations - 1; iComputation++ ) { fsi::vector data; if ( i == 0 ) data = solidSolvers.at( iComputation )->r; else data = solidSolvers.at( iComputation )->u; scalar error = (ref - data).norm() / ref.norm(); errors.push_back( error ); } for ( int iComputation = 0; iComputation < nbComputations - 2; iComputation++ ) { scalar order = ( std::log10( errors.at( iComputation ) ) - std::log10( errors.at( iComputation + 1 ) ) ) / ( std::log10( nbTimeStepsList.at( iComputation + 1 ) ) - std::log10( nbTimeStepsList.at( iComputation ) ) ); std::cout << "order = " << order << std::endl; if ( i == 0 ) ASSERT_NEAR( order, 3, 0.1 ); } } std::cout << "fluid" << std::endl; for ( int i = 0; i < 3; i++ ) { fsi::vector ref; if ( i == 0 ) ref = fluidSolvers.back()->u; if ( i == 1 ) ref = fluidSolvers.back()->a; if ( i == 2 ) ref = fluidSolvers.back()->p; std::deque<scalar> errors; for ( int iComputation = 0; iComputation < nbComputations - 1; iComputation++ ) { fsi::vector data; if ( i == 0 ) data = fluidSolvers.at( iComputation )->u; if ( i == 1 ) data = fluidSolvers.at( iComputation )->a; if ( i == 2 ) data = fluidSolvers.at( iComputation )->p; scalar error = (ref - data).norm() / ref.norm(); errors.push_back( error ); } for ( int iComputation = 0; iComputation < nbComputations - 2; iComputation++ ) { scalar order = ( std::log10( errors.at( iComputation ) ) - std::log10( errors.at( iComputation + 1 ) ) ) / ( std::log10( nbTimeStepsList.at( iComputation + 1 ) ) - std::log10( nbTimeStepsList.at( iComputation ) ) ); std::cout << "order = " << order << std::endl; if ( i == 1 || i == 2 ) ASSERT_NEAR( order, 3, 0.1 ); } } }
TEST( SDCFsiTest, reuse ) { std::vector<int> nbIter; for ( int nbReuse = 0; nbReuse < 3; nbReuse++ ) { scalar r0 = 0.2; scalar a0 = M_PI * r0 * r0; scalar u0 = 0.1; scalar p0 = 0; scalar dt = 0.01; int N = 20; scalar L = 1; scalar T = 1; scalar dx = L / N; scalar rho = 1.225; scalar E = 490; scalar h = 1.0e-3; scalar cmk = std::sqrt( E * h / (2 * rho * r0) ); scalar c0 = std::sqrt( cmk * cmk - p0 / (2 * rho) ); scalar kappa = c0 / u0; bool parallel = false; int extrapolation = 0; scalar tol = 1.0e-5; int maxIter = 50; scalar initialRelaxation = 1.0e-3; int maxUsedIterations = 50; scalar singularityLimit = 1.0e-13; int reuseInformationStartingFromTimeIndex = 0; bool scaling = false; bool updateJacobian = false; scalar beta = 0.1; int minIter = 5; ASSERT_NEAR( kappa, 10, 1.0e-13 ); ASSERT_TRUE( dx > 0 ); std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> fluid( new tubeflow::SDCTubeFlowFluidSolver( a0, u0, p0, dt, cmk, N, L, T, rho ) ); std::shared_ptr<tubeflow::SDCTubeFlowSolidSolver> solid( new tubeflow::SDCTubeFlowSolidSolver( a0, cmk, p0, rho, L, N ) ); shared_ptr<RBFFunctionInterface> rbfFunction; shared_ptr<RBFInterpolation> rbfInterpolator; shared_ptr<RBFCoarsening> rbfInterpToCouplingMesh; shared_ptr<RBFCoarsening> rbfInterpToMesh; rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> fluidSolver( new MultiLevelSolver( fluid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 0, 0 ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> solidSolver( new MultiLevelSolver( solid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 1, 0 ) ); std::shared_ptr< std::list<std::shared_ptr<ConvergenceMeasure> > > convergenceMeasures; convergenceMeasures = std::shared_ptr<std::list<std::shared_ptr<ConvergenceMeasure> > >( new std::list<std::shared_ptr<ConvergenceMeasure> > ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new RelativeConvergenceMeasure( 0, false, tol ) ) ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new MinIterationConvergenceMeasure( 0, false, minIter ) ) ); shared_ptr<MultiLevelFsiSolver> fsi( new MultiLevelFsiSolver( fluidSolver, solidSolver, convergenceMeasures, parallel, extrapolation ) ); shared_ptr<PostProcessing> postProcessing( new AndersonPostProcessing( fsi, maxIter, initialRelaxation, maxUsedIterations, nbReuse, singularityLimit, reuseInformationStartingFromTimeIndex, scaling, beta, updateJacobian ) ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcFluidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( fluid ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcSolidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( solid ); assert( sdcFluidSolver ); assert( sdcSolidSolver ); std::shared_ptr<fsi::SDCFsiSolver> fsiSolver( new fsi::SDCFsiSolver( sdcFluidSolver, sdcSolidSolver, postProcessing, extrapolation ) ); int nbNodes = 3; std::shared_ptr<fsi::quadrature::IQuadrature<scalar> > quadrature; quadrature = std::shared_ptr<fsi::quadrature::IQuadrature<scalar> >( new fsi::quadrature::Uniform<scalar>( nbNodes ) ); std::shared_ptr<sdc::SDC> sdc( new sdc::SDC( fsiSolver, quadrature, 1.0e-10, nbNodes, nbNodes ) ); sdc->run(); nbIter.push_back( fsi->nbIter ); } int iprev; int index = 0; for ( int i : nbIter ) { std::cout << "nbIter = " << i << std::endl; if ( index > 0 ) ASSERT_LE( i, iprev ); iprev = i; index++; } }
virtual void SetUp() { scalar r0 = 3.0e-3; scalar h = 3.0e-4; scalar L = 0.126; scalar rho_s = 1000; scalar E0 = 4.0e5; scalar G = 4.0e5; scalar nu = 0.5; scalar a0 = M_PI * r0 * r0; scalar u0 = 0.26; scalar p0 = 0; scalar dt = 1; int N = 5; scalar T = 1; scalar rho_f = 1060; scalar E = 490; scalar cmk = std::sqrt( E * h / (2 * rho_f * r0) ); bool parallel = false; int extrapolation = 0; scalar tol = 1.0e-3; int maxIter = 20; scalar initialRelaxation = 1.0e-3; int maxUsedIterations = 50; int nbReuse = 0; scalar singularityLimit = 1.0e-13; int reuseInformationStartingFromTimeIndex = 0; bool scaling = false; bool updateJacobian = false; scalar beta = 0.5; int minIter = 5; std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> fluid( new tubeflow::SDCTubeFlowFluidSolver( a0, u0, p0, dt, cmk, N, L, T, rho_f ) ); std::shared_ptr<fsi::BaseMultiLevelSolver> solid; solid = std::shared_ptr<fsi::BaseMultiLevelSolver>( new tubeflow::SDCTubeFlowLinearizedSolidSolver( N, nu, rho_s, h, L, dt, G, E0, r0, T ) ); assert( solid ); shared_ptr<RBFFunctionInterface> rbfFunction; shared_ptr<RBFInterpolation> rbfInterpolator; shared_ptr<RBFCoarsening> rbfInterpToCouplingMesh; shared_ptr<RBFCoarsening> rbfInterpToMesh; rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> fluidSolver( new MultiLevelSolver( fluid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 0, 0 ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> solidSolver( new MultiLevelSolver( solid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 1, 0 ) ); std::shared_ptr< std::list<std::shared_ptr<ConvergenceMeasure> > > convergenceMeasures; convergenceMeasures = std::shared_ptr<std::list<std::shared_ptr<ConvergenceMeasure> > >( new std::list<std::shared_ptr<ConvergenceMeasure> >() ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new RelativeConvergenceMeasure( 0, true, tol ) ) ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new MinIterationConvergenceMeasure( 0, false, minIter ) ) ); shared_ptr<MultiLevelFsiSolver> fsi( new MultiLevelFsiSolver( fluidSolver, solidSolver, convergenceMeasures, parallel, extrapolation ) ); shared_ptr<PostProcessing> postProcessing( new AndersonPostProcessing( fsi, maxIter, initialRelaxation, maxUsedIterations, nbReuse, singularityLimit, reuseInformationStartingFromTimeIndex, scaling, beta, updateJacobian ) ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcFluidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( fluid ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcSolidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( solid ); assert( sdcFluidSolver ); assert( sdcSolidSolver ); std::shared_ptr<fsi::SDCFsiSolver> fsiSolver( new fsi::SDCFsiSolver( sdcFluidSolver, sdcSolidSolver, postProcessing, extrapolation ) ); std::shared_ptr<sdc::AdaptiveTimeStepper> adaptiveTimeStepper( new sdc::AdaptiveTimeStepper( false ) ); std::string method = "ESDIRK53PR"; esdirk = std::shared_ptr<sdc::ESDIRK> ( new sdc::ESDIRK( fsiSolver, method, adaptiveTimeStepper ) ); }
TEST( SDCFsiTest, order ) { int N = 5; scalar r0 = 0.2; scalar a0 = M_PI * r0 * r0; scalar u0 = 0.1; scalar p0 = 0; scalar L = 1; scalar T = 1; scalar dx = L / N; scalar rho = 1.225; scalar E = 490; scalar h = 1.0e-3; scalar cmk = std::sqrt( E * h / (2 * rho * r0) ); scalar c0 = std::sqrt( cmk * cmk - p0 / (2 * rho) ); scalar kappa = c0 / u0; bool parallel = false; int extrapolation = 0; scalar tol = 1.0e-5; int maxIter = 20; scalar initialRelaxation = 1.0e-3; int maxUsedIterations = 50; int nbReuse = 0; scalar singularityLimit = 1.0e-13; int reuseInformationStartingFromTimeIndex = 0; bool scaling = false; scalar beta = 0.01; bool updateJacobian = false; int minIter = 5; ASSERT_NEAR( kappa, 10, 1.0e-13 ); ASSERT_TRUE( dx > 0 ); int nbComputations = 5; std::deque<std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> > fluidSolvers; std::deque<int> nbTimeStepsList; for ( int iComputation = 0; iComputation < nbComputations; iComputation++ ) { int nbTimeSteps = 4 * std::pow( 2, iComputation ); std::cout << "nbTimeSteps = " << nbTimeSteps << std::endl; scalar dt = T / nbTimeSteps; std::shared_ptr<tubeflow::SDCTubeFlowFluidSolver> fluid( new tubeflow::SDCTubeFlowFluidSolver( a0, u0, p0, dt, cmk, N, L, T, rho ) ); std::shared_ptr<tubeflow::SDCTubeFlowSolidSolver> solid( new tubeflow::SDCTubeFlowSolidSolver( a0, cmk, p0, rho, L, N ) ); shared_ptr<RBFFunctionInterface> rbfFunction; shared_ptr<RBFInterpolation> rbfInterpolator; shared_ptr<RBFCoarsening> rbfInterpToCouplingMesh; shared_ptr<RBFCoarsening> rbfInterpToMesh; rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> fluidSolver( new MultiLevelSolver( fluid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 0, 0 ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToCouplingMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); rbfFunction = shared_ptr<RBFFunctionInterface>( new TPSFunction() ); rbfInterpolator = shared_ptr<RBFInterpolation>( new RBFInterpolation( rbfFunction ) ); rbfInterpToMesh = shared_ptr<RBFCoarsening> ( new RBFCoarsening( rbfInterpolator ) ); shared_ptr<MultiLevelSolver> solidSolver( new MultiLevelSolver( solid, fluid, rbfInterpToCouplingMesh, rbfInterpToMesh, 1, 0 ) ); std::shared_ptr< std::list<std::shared_ptr<ConvergenceMeasure> > > convergenceMeasures; convergenceMeasures = std::shared_ptr<std::list<std::shared_ptr<ConvergenceMeasure> > >( new std::list<std::shared_ptr<ConvergenceMeasure> > ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new ResidualRelativeConvergenceMeasure( 0, false, tol ) ) ); convergenceMeasures->push_back( std::shared_ptr<ConvergenceMeasure>( new MinIterationConvergenceMeasure( 0, false, minIter ) ) ); shared_ptr<MultiLevelFsiSolver> fsi( new MultiLevelFsiSolver( fluidSolver, solidSolver, convergenceMeasures, parallel, extrapolation ) ); shared_ptr<PostProcessing> postProcessing( new AndersonPostProcessing( fsi, maxIter, initialRelaxation, maxUsedIterations, nbReuse, singularityLimit, reuseInformationStartingFromTimeIndex, scaling, beta, updateJacobian ) ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcFluidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( fluid ); std::shared_ptr<sdc::SDCFsiSolverInterface> sdcSolidSolver = std::dynamic_pointer_cast<sdc::SDCFsiSolverInterface>( solid ); assert( sdcFluidSolver ); assert( sdcSolidSolver ); std::shared_ptr<fsi::SDCFsiSolver> fsiSolver( new fsi::SDCFsiSolver( sdcFluidSolver, sdcSolidSolver, postProcessing, extrapolation ) ); int nbNodes = 3; std::shared_ptr<fsi::quadrature::IQuadrature<scalar> > quadrature; quadrature = std::shared_ptr<fsi::quadrature::IQuadrature<scalar> >( new fsi::quadrature::GaussLobatto<scalar>( nbNodes ) ); std::shared_ptr<sdc::SDC> sdc( new sdc::SDC( fsiSolver, quadrature, 1.0e-13, 10, 200 ) ); sdc->run(); ASSERT_TRUE( sdc->isConverged() ); fluidSolvers.push_back( fluid ); nbTimeStepsList.push_back( nbTimeSteps ); } for ( int i = 0; i < 2; i++ ) { fsi::vector ref; if ( i == 0 ) ref = fluidSolvers.back()->u; else ref = fluidSolvers.back()->a; std::deque<scalar> errors; for ( int iComputation = 0; iComputation < nbComputations - 1; iComputation++ ) { fsi::vector data; if ( i == 0 ) data = fluidSolvers.at( iComputation )->u; else data = fluidSolvers.at( iComputation )->a; scalar error = (ref - data).norm() / data.norm(); std::cout << "error = " << error << std::endl; errors.push_back( error ); } for ( int iComputation = 0; iComputation < nbComputations - 2; iComputation++ ) { scalar order = ( std::log10( errors.at( iComputation ) ) - std::log10( errors.at( iComputation + 1 ) ) ) / ( std::log10( nbTimeStepsList.at( iComputation + 1 ) ) - std::log10( nbTimeStepsList.at( iComputation ) ) ); std::cout << "order = " << order << std::endl; ASSERT_GE( order, 3.8 ); } } }