Public Types |
Public Member Functions |
Public Attributes |
Static Public Attributes |
Protected Attributes |
Static Protected Attributes |
List of all members
Opm::BlackoilModel< TypeTag > Class Template Reference
Detailed Descriptiontemplate<class TypeTag> class Opm::BlackoilModel< TypeTag > A model implementation for three-phase black oil. The simulator is capable of handling three-phase problems where gas can be dissolved in oil and vice versa. It uses an industry-standard TPFA discretization with per-phase upwind weighting of mobilities. Member Typedef Documentation◆ BVector
template<class TypeTag >
◆ ComponentName
template<class TypeTag >
◆ ElementContext
template<class TypeTag >
◆ FluidSystem
template<class TypeTag >
◆ Grid
template<class TypeTag >
◆ Indices
template<class TypeTag >
◆ IntensiveQuantities
template<class TypeTag >
◆ Mat
template<class TypeTag >
◆ MaterialLaw
template<class TypeTag >
◆ MaterialLawParams
template<class TypeTag >
◆ MatrixBlockType
template<class TypeTag >
◆ ModelParameters
template<class TypeTag >
◆ PrimaryVariables
template<class TypeTag >
◆ Scalar
template<class TypeTag >
◆ Simulator
template<class TypeTag >
◆ SolutionVector
template<class TypeTag >
◆ SparseMatrixAdapter
template<class TypeTag >
◆ VectorBlockType
template<class TypeTag >
Constructor & Destructor Documentation◆ BlackoilModel()
template<class TypeTag >
Construct the model. It will retain references to the arguments of this functions, and they are expected to remain in scope for the lifetime of the solver.
References Opm::BlackoilModel< TypeTag >::convergence_reports_, Opm::detail::countGlobalCells(), Opm::BlackoilModel< TypeTag >::global_nc_, Opm::BlackoilModel< TypeTag >::grid_, Opm::BlackoilModelParameters< Scalar >::matrix_add_well_contributions_, Opm::BlackoilModel< TypeTag >::nlddSolver_, Opm::BlackoilModelParameters< Scalar >::nonlinear_solver_, and Opm::BlackoilModel< TypeTag >::param_. Member Function Documentation◆ afterStep()
template<class TypeTag >
Called once after each time step. In this class, this function does nothing.
References Opm::RSTConv::getData(), Opm::SimulatorReportSingle::pre_post_time, Opm::BlackoilModel< TypeTag >::rst_conv_, and Opm::BlackoilModel< TypeTag >::simulator_. ◆ assembleReservoir()
template<class TypeTag >
Assemble the residual and Jacobian of the nonlinear system. References Opm::BlackoilModel< TypeTag >::simulator_, and Opm::BlackoilModel< TypeTag >::wellModel(). Referenced by Opm::BlackoilModel< TypeTag >::initialLinearization(). ◆ beginReportStep()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::simulator_. ◆ characteriseCnvPvSplit()
template<class TypeTag >
Compute pore-volume/cell count split among "converged", "relaxed converged", "unconverged" cells based on CNV point measures. References Opm::BlackoilModel< TypeTag >::grid_, OPM_BEGIN_PARALLEL_TRY_CATCH, OPM_END_PARALLEL_TRY_CATCH, Opm::BlackoilModel< TypeTag >::param_, Opm::BlackoilModel< TypeTag >::simulator(), Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_, and Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_relaxed_. Referenced by Opm::BlackoilModel< TypeTag >::getReservoirConvergence(). ◆ compNames()
template<class TypeTag >
Returns const reference to component names. References Opm::BlackoilModel< TypeTag >::compNames_. ◆ computeFluidInPlace() [1/2]
template<class TypeTag >
Should not be called. References Opm::BlackoilModel< TypeTag >::computeFluidInPlace(). ◆ computeFluidInPlace() [2/2]
template<class TypeTag >
template<class T >
Wrapper required due to not following generic API. References Opm::BlackoilModel< TypeTag >::computeFluidInPlace(). Referenced by Opm::BlackoilModel< TypeTag >::computeFluidInPlace(). ◆ convergenceReduction()
template<class TypeTag >
◆ eclState()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::simulator_. ◆ endReportStep()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::simulator_. ◆ failureReport()
template<class TypeTag >
return the statistics if the nonlinearIteration() method failed References Opm::BlackoilModel< TypeTag >::failureReport_. ◆ getConvCells()
template<class TypeTag >
References Opm::RSTConv::getData(), and Opm::BlackoilModel< TypeTag >::rst_conv_. ◆ getConvergence()
template<class TypeTag >
Compute convergence based on total mass balance (tol_mb) and maximum residual mass balance (tol_cnv).
References Opm::SimulatorTimerInterface::currentStepLength(), Opm::BlackoilModel< TypeTag >::getConvergence(), Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), Opm::BlackoilModel< TypeTag >::numEq, Opm::SimulatorTimerInterface::simulationTimeElapsed(), and Opm::BlackoilModel< TypeTag >::wellModel(). Referenced by Opm::BlackoilModel< TypeTag >::getConvergence(), and Opm::BlackoilModel< TypeTag >::initialLinearization(). ◆ getMaxCoeff()
template<class TypeTag >
template<class FluidState , class Residual >
References Opm::BlackoilModel< TypeTag >::contiBiofilmEqIdx, Opm::BlackoilModel< TypeTag >::contiBrineEqIdx, Opm::BlackoilModel< TypeTag >::contiCalciteEqIdx, Opm::BlackoilModel< TypeTag >::contiEnergyEqIdx, Opm::BlackoilModel< TypeTag >::contiFoamEqIdx, Opm::BlackoilModel< TypeTag >::contiMicrobialEqIdx, Opm::BlackoilModel< TypeTag >::contiOxygenEqIdx, Opm::BlackoilModel< TypeTag >::contiPolymerEqIdx, Opm::BlackoilModel< TypeTag >::contiPolymerMWEqIdx, Opm::BlackoilModel< TypeTag >::contiSolventEqIdx, Opm::BlackoilModel< TypeTag >::contiUreaEqIdx, Opm::BlackoilModel< TypeTag >::contiZfracEqIdx, Opm::BlackoilModel< TypeTag >::has_brine_, Opm::BlackoilModel< TypeTag >::has_energy_, Opm::BlackoilModel< TypeTag >::has_extbo_, Opm::BlackoilModel< TypeTag >::has_foam_, Opm::BlackoilModel< TypeTag >::has_micp_, Opm::BlackoilModel< TypeTag >::has_polymer_, Opm::BlackoilModel< TypeTag >::has_polymermw_, and Opm::BlackoilModel< TypeTag >::has_solvent_. Referenced by Opm::BlackoilModel< TypeTag >::localConvergenceData(). ◆ getReservoirConvergence()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::characteriseCnvPvSplit(), Opm::BlackoilModel< TypeTag >::compNames_, Opm::BlackoilModel< TypeTag >::contiEnergyEqIdx, Opm::BlackoilModel< TypeTag >::convergenceReduction(), Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), Opm::BlackoilModel< TypeTag >::grid_, Opm::BlackoilModel< TypeTag >::has_energy_, Opm::BlackoilModel< TypeTag >::localConvergenceData(), Opm::BlackoilModelParameters< Scalar >::min_strict_cnv_iter_, Opm::BlackoilModelParameters< Scalar >::min_strict_mb_iter_, Opm::ComponentName< FluidSystem, Indices >::name(), Opm::BlackoilModel< TypeTag >::numEq, Opm::BlackoilModel< TypeTag >::param_, Opm::BlackoilModelParameters< Scalar >::relaxed_max_pv_fraction_, Opm::ConvergenceReport::setReservoirFailed(), Opm::BlackoilModel< TypeTag >::terminal_output_, Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_, Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_energy_, Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_energy_relaxed_, Opm::BlackoilModelParameters< Scalar >::tolerance_cnv_relaxed_, Opm::BlackoilModelParameters< Scalar >::tolerance_energy_balance_, Opm::BlackoilModelParameters< Scalar >::tolerance_energy_balance_relaxed_, Opm::BlackoilModelParameters< Scalar >::tolerance_mb_, and Opm::BlackoilModelParameters< Scalar >::tolerance_mb_relaxed_. Referenced by Opm::BlackoilModel< TypeTag >::getConvergence(), and Opm::BlackoilModel< TypeTag >::getReservoirConvergence(). ◆ initialLinearization()
template<class TypeTag >
References Opm::SimulatorReportSingle::assemble_time, Opm::BlackoilModel< TypeTag >::assembleReservoir(), Opm::SimulatorReportSingle::converged, Opm::BlackoilModel< TypeTag >::convergence_reports_, Opm::BlackoilModel< TypeTag >::failureReport_, Opm::BlackoilModel< TypeTag >::getConvergence(), Opm::ConvergenceReport::NotANumber, Opm::BlackoilModel< TypeTag >::residual_norms_history_, Opm::ConvergenceReport::TooLarge, Opm::SimulatorReportSingle::total_linearizations, and Opm::SimulatorReportSingle::update_time. Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(). ◆ isParallel()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::grid_. ◆ linearIterationsLastSolve()
template<class TypeTag >
Number of linear iterations used in last call to solveJacobianSystem(). References Opm::BlackoilModel< TypeTag >::simulator_. Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(). ◆ linearSolveSetupTime()
template<class TypeTag >
◆ localAccumulatedReports()
template<class TypeTag >
return the statistics if the nonlinearIteration() method failed References Opm::BlackoilModel< TypeTag >::nlddSolver_. ◆ localConvergenceData()
template<class TypeTag >
Get reservoir quantities on this process needed for convergence calculations.
References Opm::BlackoilModel< TypeTag >::getMaxCoeff(), Opm::BlackoilModel< TypeTag >::global_nc_, Opm::BlackoilModel< TypeTag >::grid_, Opm::BlackoilModel< TypeTag >::localConvergenceData(), OPM_BEGIN_PARALLEL_TRY_CATCH, OPM_END_PARALLEL_TRY_CATCH, Opm::BlackoilModel< TypeTag >::simulator(), and Opm::BlackoilModel< TypeTag >::simulator_. Referenced by Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), and Opm::BlackoilModel< TypeTag >::localConvergenceData(). ◆ nonlinearIteration()
template<class TypeTag >
template<class NonlinearSolverType >
Called once per nonlinear iteration. This model will perform a Newton-Raphson update, changing reservoir_state and well_state. It will also use the nonlinear_solver to do relaxation of updates if necessary.
References Opm::BlackoilModel< TypeTag >::convergence_reports_, Opm::BlackoilModel< TypeTag >::current_relaxation_, Opm::SimulatorTimerInterface::currentStepNum(), Opm::BlackoilModel< TypeTag >::dx_old_, Opm::BlackoilModelParameters< Scalar >::nldd_num_initial_newton_iter_, Opm::BlackoilModel< TypeTag >::nlddSolver_, Opm::BlackoilModelParameters< Scalar >::nonlinear_solver_, Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(), Opm::BlackoilModel< TypeTag >::param_, Opm::SimulatorTimerInterface::reportStepNum(), Opm::BlackoilModel< TypeTag >::residual_norms_history_, Opm::BlackoilModel< TypeTag >::rst_conv_, Opm::BlackoilModel< TypeTag >::simulator_, and Opm::RSTConv::update(). ◆ nonlinearIterationNewton()
template<class TypeTag >
template<class NonlinearSolverType >
References Opm::SimulatorReportSingle::converged, Opm::BlackoilModel< TypeTag >::current_relaxation_, Opm::BlackoilModel< TypeTag >::dx_old_, Opm::BlackoilModel< TypeTag >::failureReport_, Opm::BlackoilModel< TypeTag >::initialLinearization(), Opm::SimulatorReportSingle::linear_solve_setup_time, Opm::SimulatorReportSingle::linear_solve_time, Opm::BlackoilModel< TypeTag >::linearIterationsLastSolve(), Opm::BlackoilModel< TypeTag >::param_, Opm::BlackoilModel< TypeTag >::residual_norms_history_, Opm::BlackoilModel< TypeTag >::simulator(), Opm::BlackoilModel< TypeTag >::simulator_, Opm::BlackoilModel< TypeTag >::solveJacobianSystem(), Opm::BlackoilModel< TypeTag >::terminalOutputEnabled(), Opm::to_string(), Opm::SimulatorReportSingle::total_linear_iterations, Opm::SimulatorReportSingle::total_newton_iterations, Opm::SimulatorReportSingle::update_time, Opm::BlackoilModel< TypeTag >::updateSolution(), Opm::BlackoilModelParameters< Scalar >::use_update_stabilization_, and Opm::BlackoilModel< TypeTag >::wellModel(). Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIteration(). ◆ numPhases()
template<class TypeTag >
The number of active fluid phases in the model. References Opm::PhaseUsage::num_phases, and Opm::BlackoilModel< TypeTag >::phaseUsage_. ◆ param()
template<class TypeTag >
Returns const reference to model parameters. References Opm::BlackoilModel< TypeTag >::param_. ◆ prepareStep()
template<class TypeTag >
Called once before each time step.
References Opm::SimulatorTimerInterface::currentStepLength(), Opm::RSTConv::init(), Opm::SimulatorTimerInterface::lastStepFailed(), Opm::BlackoilModel< TypeTag >::nlddSolver_, Opm::BlackoilModel< TypeTag >::param_, Opm::SimulatorReportSingle::pre_post_time, Opm::SimulatorTimerInterface::reportStepNum(), Opm::BlackoilModel< TypeTag >::rst_conv_, Opm::SimulatorTimerInterface::simulationTimeElapsed(), Opm::BlackoilModel< TypeTag >::simulator_, Opm::BlackoilModelParameters< Scalar >::update_equations_scaling_, and Opm::BlackoilModel< TypeTag >::wasSwitched_. ◆ relativeChange()
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::simulator_. ◆ simulator() [1/2]
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::simulator_. ◆ simulator() [2/2]
template<class TypeTag >
◆ solveJacobianSystem()
template<class TypeTag >
Solve the Jacobian system Jx = r where J is the Jacobian and r is the residual. References Opm::BlackoilModel< TypeTag >::grid_, Opm::BlackoilModel< TypeTag >::simulator_, and Opm::BlackoilModel< TypeTag >::terminal_output_. Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(). ◆ stepReports()
template<class TypeTag >
◆ terminalOutputEnabled()
template<class TypeTag >
Return true if output to cout is wanted. References Opm::BlackoilModel< TypeTag >::terminal_output_. Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(). ◆ updateSolution()
template<class TypeTag >
Apply an update to the primary variables. References Opm::BlackoilModel< TypeTag >::simulator_, and Opm::BlackoilModel< TypeTag >::updateSolution(). Referenced by Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(), and Opm::BlackoilModel< TypeTag >::updateSolution(). ◆ updateTUNING()
template<class TypeTag >
◆ wellModel() [1/2]
template<class TypeTag >
return the StandardWells object References Opm::BlackoilModel< TypeTag >::well_model_. Referenced by Opm::BlackoilModel< TypeTag >::assembleReservoir(), Opm::BlackoilModel< TypeTag >::getConvergence(), and Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(). ◆ wellModel() [2/2]
template<class TypeTag >
References Opm::BlackoilModel< TypeTag >::well_model_. ◆ writePartitions()
template<class TypeTag >
Member Data Documentation◆ biofilmConcentrationIdx
template<class TypeTag >
◆ calciteConcentrationIdx
template<class TypeTag >
◆ compNames_
template<class TypeTag >
◆ contiBiofilmEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiBrineEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiCalciteEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiEnergyEqIdx
template<class TypeTag >
◆ contiFoamEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiMicrobialEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiOxygenEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiPolymerEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiPolymerMWEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiSolventEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiUreaEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ contiZfracEqIdx
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ convergence_reports_
template<class TypeTag >
◆ current_relaxation_
template<class TypeTag >
◆ dx_old_
template<class TypeTag >
◆ failureReport_
template<class TypeTag >
◆ foamConcentrationIdx
template<class TypeTag >
◆ global_nc_
template<class TypeTag >
The number of cells of the global grid. Referenced by Opm::BlackoilModel< TypeTag >::BlackoilModel(), and Opm::BlackoilModel< TypeTag >::localConvergenceData(). ◆ grid_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::BlackoilModel(), Opm::BlackoilModel< TypeTag >::characteriseCnvPvSplit(), Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), Opm::BlackoilModel< TypeTag >::isParallel(), Opm::BlackoilModel< TypeTag >::localConvergenceData(), and Opm::BlackoilModel< TypeTag >::solveJacobianSystem(). ◆ has_brine_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_energy_
template<class TypeTag >
◆ has_extbo_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_foam_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_micp_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_polymer_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_polymermw_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ has_solvent_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::getMaxCoeff(). ◆ microbialConcentrationIdx
template<class TypeTag >
◆ nlddSolver_
template<class TypeTag >
◆ numEq
template<class TypeTag >
◆ oxygenConcentrationIdx
template<class TypeTag >
◆ param_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::BlackoilModel(), Opm::BlackoilModel< TypeTag >::characteriseCnvPvSplit(), Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), Opm::BlackoilModel< TypeTag >::nonlinearIteration(), Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(), Opm::BlackoilModel< TypeTag >::param(), Opm::BlackoilModel< TypeTag >::prepareStep(), and Opm::BlackoilModel< TypeTag >::updateTUNING(). ◆ phaseUsage_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::numPhases(). ◆ polymerConcentrationIdx
template<class TypeTag >
◆ polymerMoleWeightIdx
template<class TypeTag >
◆ residual_norms_history_
template<class TypeTag >
◆ rst_conv_
template<class TypeTag >
Helper class for RPTRST CONV. Referenced by Opm::BlackoilModel< TypeTag >::afterStep(), Opm::BlackoilModel< TypeTag >::getConvCells(), Opm::BlackoilModel< TypeTag >::nonlinearIteration(), and Opm::BlackoilModel< TypeTag >::prepareStep(). ◆ saltConcentrationIdx
template<class TypeTag >
◆ simulator_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::afterStep(), Opm::BlackoilModel< TypeTag >::assembleReservoir(), Opm::BlackoilModel< TypeTag >::beginReportStep(), Opm::BlackoilModel< TypeTag >::eclState(), Opm::BlackoilModel< TypeTag >::endReportStep(), Opm::BlackoilModel< TypeTag >::linearIterationsLastSolve(), Opm::BlackoilModel< TypeTag >::localConvergenceData(), Opm::BlackoilModel< TypeTag >::nonlinearIteration(), Opm::BlackoilModel< TypeTag >::nonlinearIterationNewton(), Opm::BlackoilModel< TypeTag >::prepareStep(), Opm::BlackoilModel< TypeTag >::relativeChange(), Opm::BlackoilModel< TypeTag >::simulator(), Opm::BlackoilModel< TypeTag >::solveJacobianSystem(), and Opm::BlackoilModel< TypeTag >::updateSolution(). ◆ solventSaturationIdx
template<class TypeTag >
◆ temperatureIdx
template<class TypeTag >
◆ terminal_output_
template<class TypeTag >
Whether we print something to std::cout. Referenced by Opm::BlackoilModel< TypeTag >::getReservoirConvergence(), Opm::BlackoilModel< TypeTag >::solveJacobianSystem(), Opm::BlackoilModel< TypeTag >::terminalOutputEnabled(), and Opm::BlackoilModel< TypeTag >::updateTUNING(). ◆ ureaConcentrationIdx
template<class TypeTag >
◆ wasSwitched_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::prepareStep(). ◆ well_model_
template<class TypeTag >
Referenced by Opm::BlackoilModel< TypeTag >::wellModel(). ◆ zFractionIdx
template<class TypeTag >
The documentation for this class was generated from the following file: |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||