00001
00009 #ifndef BS_FI_OPERATOR_CALC_STEP_DT_MULT_H_
00010 #define BS_FI_OPERATOR_CALC_STEP_DT_MULT_H_
00011
00012 namespace blue_sky {
00013
00020 template <class strategy_t, bool is_w, bool is_g, bool is_o>
00021 BS_FORCE_INLINE typename strategy_t::item_t
00022 fi_operator_impl <strategy_t, is_w, is_g, is_o>::calc_step_dt_mult (item_t prev_mult, item_t max_res)
00023 {
00024 item_t coef = 1.0, m_r, d, d_mult;
00025 index_t i;
00026 index_t equ_w, equ_g, equ_o;
00027 #ifdef _MPI
00028 index_t n_left = 0;
00029 index_t n_own = 0;
00030 item_t mpi_coef;
00031 #endif //_MPI
00032
00033
00034 #ifdef _MPI
00035 for (i = n_left; i < n_own; ++i)
00036 #else
00037 for (i = 0; i < n_cells_; ++i)
00038 #endif
00039 {
00040 if (n_phases == 3)
00041 {
00042 equ_w = i * n_phases + p3_wat;
00043 equ_g = i * n_phases + p3_gas;
00044 equ_o = i * n_phases + p3_oil;
00045 }
00046 else if (n_phases == 2 && is_w)
00047 {
00048 equ_w = i * n_phases + p2ow_wat;
00049 equ_o = i * n_phases + p2ow_oil;
00050 }
00051 else if (n_phases == 2 && is_g)
00052 {
00053 equ_g = i * n_phases + p2og_gas;
00054 equ_o = i * n_phases + p2og_oil;
00055 }
00056 else
00057 {
00058 equ_g = equ_w = equ_o = i * n_phases + 0;
00059 }
00060 #ifdef _MPI
00061 equ_w -= n_phases * n_left;
00062 equ_g -= n_phases * n_left;
00063 equ_o -= n_phases * n_left;
00064 #endif //_MPI
00065 d_mult = (calc_model_->ave_volume * data_[i].porosity);
00066 if (is_w)
00067 {
00068 m_r = max_res * d_mult * calc_model_->invers_fvf_average[d_w];
00069 if (rhs_[equ_w] * flux_rhs_[equ_w] <= EPS_DIV
00070 && fabs (flux_rhs_[equ_w]) > fabs (rhs_[equ_w])
00071 && fabs (flux_rhs_[equ_w] + rhs_[equ_w]) > m_r)
00072 {
00073 if (flux_rhs_[equ_w] > 0)
00074 d = (m_r - rhs_[equ_w]) / flux_rhs_[equ_w];
00075 else
00076 d = -(m_r + rhs_[equ_w]) / flux_rhs_[equ_w];
00077 if (d < coef)
00078 coef = d;
00079 }
00080 }
00081 if (is_g)
00082 {
00083 m_r = max_res * d_mult * calc_model_->invers_fvf_average[d_g];
00084 if (rhs_[equ_g] * flux_rhs_[equ_g] <= EPS_DIV
00085 && fabs (flux_rhs_[equ_g]) > fabs (rhs_[equ_g])
00086 && fabs (flux_rhs_[equ_g] + rhs_[equ_g]) > m_r)
00087 {
00088 if (flux_rhs_[equ_g] > 0)
00089 d = (m_r - rhs_[equ_g]) / flux_rhs_[equ_g];
00090 else
00091 d = -(m_r + rhs_[equ_g]) / flux_rhs_[equ_g];
00092 if (d < coef)
00093 coef = d;
00094 }
00095 }
00096 if (is_o)
00097 {
00098 m_r = max_res * d_mult * calc_model_->invers_fvf_average[d_o];
00099 if (rhs_[equ_o] * flux_rhs_[equ_o] <= EPS_DIV
00100 && fabs (flux_rhs_[equ_o]) > fabs (rhs_[equ_o])
00101 && fabs (flux_rhs_[equ_o] + rhs_[equ_o]) > m_r)
00102 {
00103 if (flux_rhs_[equ_o] > 0)
00104 d = (m_r - rhs_[equ_o]) / flux_rhs_[equ_o];
00105 else
00106 d = -(m_r + rhs_[equ_o]) / flux_rhs_[equ_o];
00107 if (d < coef)
00108 coef = d;
00109 }
00110 }
00111
00112 }
00113 if (coef < prev_mult)
00114 coef = prev_mult;
00115
00116 #ifdef _MPI
00117 MPI_Allreduce (&coef, &mpi_coef, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
00118 coef = mpi_coef;
00119 #endif
00120 return coef;
00121 }
00122
00123 }
00124
00125
00126 #endif // #ifndef BS_FI_OPERATOR_CALC_STEP_DT_MULT_H_
00127