56 template<
unsigned int TDim>
67 using VariantTableauType = std::variant<ButcherTableauForwardEuler, ButcherTableauMidPointMethod, ButcherTableauRK3TVD, ButcherTableauRK4>;
89 mpModelPart = &(rModel.
GetModelPart(ThisParameters[
"model_part_name"].GetString()));
92 mpEdgeDataStructure = Kratos::make_unique<EdgeBasedDataStructure<TDim>>();
95 mEchoLevel = ThisParameters[
"echo_level"].
GetInt();
96 mTimeSchemeName = ThisParameters[
"time_scheme"].
GetString();
97 mMaxAllowedCFL = ThisParameters[
"max_CFL"].
GetDouble();
98 mMaxAllowedDt = ThisParameters[
"max_delta_time"].
GetDouble();
99 mDiffusionConstant = ThisParameters[
"diffusion_constant"].
GetDouble();
104 KRATOS_ERROR_IF(mDiffusionConstant < 1.0e-12 || mDiffusionConstant > 1.0)
105 <<
"Provided 'diffusion_constant' " << mDiffusionConstant <<
" is not valid. Value must be between 0 and 1." << std::endl;
130 KRATOS_ERROR_IF_NOT(rNode.HasDofFor(*mpConvectedVar))
131 <<
"No DOF for convected variable '" << mpConvectedVar->Name() <<
"' in node " << rNode.Id() << std::endl;
135 mpEdgeDataStructure->CalculateEdgeDataStructure(*mpModelPart);
136 KRATOS_INFO_IF(
"FluxCorrectedTransportConvectionProcess", mEchoLevel > 0) <<
"Edge-based data structure completed." << std::endl;
139 mPerformInitialize =
false;
145 mSolution.resize(mAuxSize);
146 mSolutionOld.resize(mAuxSize);
147 mLowOrderUpdate.resize(mAuxSize);
148 mHighOrderUpdate.resize(mAuxSize);
149 mConvectionValues.resize(mAuxSize);
157 if (mPerformInitialize) {
165 double prev_time = r_prev_process_info[TIME];
166 const double target_time = r_process_info[TIME];
171 const auto it_node = mpModelPart->
NodesBegin() + iNode;
172 const IndexType i_node_id = it_node->Id();
173 mSolutionOld[i_node_id] = it_node->GetSolutionStepValue(*mpConvectedVar,1);
174 mConvectionValues[i_node_id] = it_node->GetSolutionStepValue(*mpConvectionVar,1);
178 const double target_dt = target_time - prev_time;
179 const double cfl_dt = this->CalculateSubStepDeltaTime();
180 const double max_dt =
std::min(cfl_dt, mMaxAllowedDt);
183 KRATOS_INFO_IF(
"FluxCorrectedTransportConvectionProcess", mEchoLevel > 0) << u8
"Solving FCT convection with \u0394t = " <<
dt << u8
" (max allowed \u0394t = " << max_dt <<
")" << std::endl;
188 KRATOS_INFO_IF(
"FluxCorrectedTransportConvectionProcess", mEchoLevel > 1) <<
"Substep = " <<
step <<
" - Time = " << prev_time << u8
" - \u0394t = " <<
dt << std::endl;
189 this->SolveSubStep(
dt);
197 auto it_node = mpModelPart->
NodesBegin() + iNode;
198 if (!it_node->IsFixed(*mpConvectedVar)) {
199 it_node->FastGetSolutionStepValue(*mpConvectedVar) = mSolution[it_node->Id()];
209 mSolutionOld.clear();
210 mLowOrderUpdate.clear();
211 mHighOrderUpdate.clear();
212 mConvectionValues.clear();
213 mpEdgeDataStructure->Clear();
220 "model_part_name" : "",
221 "convected_variable_name" : "DISTANCE",
222 "convection_variable_name" : "VELOCITY",
224 "max_delta_time" : 1.0,
225 "diffusion_constant" : 1.0,
226 "time_scheme" : "RK3-TVD"
229 return default_parameters;
245 std::string
Info()
const override
247 return "FluxCorrectedTransportConvectionProcess";
253 rOStream <<
"FluxCorrectedTransportConvectionProcess";
276 std::string mTimeSchemeName;
282 double mMaxAllowedDt;
284 double mMaxAllowedCFL;
286 double mDiffusionConstant;
288 bool mPerformInitialize =
true;
294 std::vector<double> mSolution;
296 std::vector<double> mSolutionOld;
298 std::vector<double> mLowOrderUpdate;
300 std::vector<double> mHighOrderUpdate;
302 std::vector<array_1d<double,3>> mConvectionValues;
315 double CalculateSubStepDeltaTime()
318 const auto& r_row_indices = mpEdgeDataStructure->
GetRowIndices();
319 const auto& r_col_indices = mpEdgeDataStructure->
GetColIndices();
326 const auto it_row = r_row_indices.begin() + iNode;
328 const SizeType n_cols = *(it_row+1) - i_col_index;
332 const double i_vel_norm =
norm_2(mConvectionValues[iNode]);
335 const auto i_col_begin = r_col_indices.begin() + i_col_index;
336 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
338 IndexType j_node_id = *(i_col_begin + j_node);
339 const double j_vel_norm =
norm_2(mConvectionValues[j_node_id]);
342 const auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iNode, j_node_id);
343 const double ij_length = r_ij_edge_data.GetLength();
346 dt_ij = CalculateEdgeLocalDeltaTime(ij_length, i_vel_norm, j_vel_norm);
360 double CalculateEdgeLocalDeltaTime(
362 const double NormVelI,
363 const double NormVelJ)
365 const double dx_CFL = Length * mMaxAllowedCFL;
366 const double dt_i = NormVelI > 1.0e-12 ? dx_CFL / NormVelI : mMaxAllowedDt;
367 const double dt_j = NormVelJ > 1.0e-12 ? dx_CFL / NormVelJ : mMaxAllowedDt;
371 void SolveSubStep(
const double DeltaTime)
374 const double low_order_max_iteration = 1;
375 const double low_order_diff_constant = mDiffusionConstant;
378 const double high_order_max_iteration = 3;
379 const double high_order_diff_constant = 0.0;
382 const auto butcher_tableau_variant = GetButcherTableauVariant();
385 const SizeType rk_steps = std::visit([](
const auto& rTableau){
return rTableau.SubstepCount();}, butcher_tableau_variant);
386 std::vector<std::vector<double>> rk_residuals_lo(mAuxSize, std::vector<double>(rk_steps, 0.0));
387 std::vector<std::vector<double>> rk_residuals_ho(mAuxSize, std::vector<double>(rk_steps, 0.0));
390 std::vector<double> rk_u_lo = mSolutionOld;
391 std::vector<double> rk_u_ho = mSolutionOld;
397 const double rk_step_theta = std::visit([&
step](
const auto &rTableau) {
return rTableau.GetIntegrationTheta(
step);}, butcher_tableau_variant);
400 CalculateResidual(rk_residuals_lo, rk_u_lo, residual_column, low_order_diff_constant, rk_step_theta * DeltaTime);
403 CalculateResidual(rk_residuals_ho, rk_u_ho, residual_column, high_order_diff_constant, rk_step_theta * DeltaTime);
405 if (
step != rk_steps) {
407 const auto [rk_mat_row_begin, rk_mat_row_end] = std::visit([&
step](
const auto& rTableau) {
return rTableau.GetMatrixRow(
step);}, butcher_tableau_variant);
408 ExplicitSolveSolution(rk_u_lo, rk_residuals_lo, DeltaTime, rk_mat_row_begin, rk_mat_row_end, low_order_max_iteration);
409 ExplicitSolveSolution(rk_u_ho, rk_residuals_ho, DeltaTime, rk_mat_row_begin, rk_mat_row_end, high_order_max_iteration);
412 IndexPartition<IndexType>(mAuxSize).for_each([&](
IndexType i){
413 mSolution[
i] = rk_u_lo[
i];
414 mHighOrderUpdate[
i] = rk_u_ho[
i] - mSolutionOld[
i];
418 double time_coeff = 0.0;
419 for (
auto it = rk_mat_row_begin; it != rk_mat_row_end; ++it) {
424 CalculateAntidiffusiveEdgeContributions(time_coeff * DeltaTime);
427 EvaluateLimiter(time_coeff * DeltaTime);
436 const auto rk_weights = std::visit([](
const auto& rTableau) ->
auto {
return rTableau.GetWeights();}, butcher_tableau_variant);
437 ExplicitSolveSolution(mSolution, rk_residuals_lo, DeltaTime, rk_weights.begin(), rk_weights.end(), low_order_max_iteration);
438 ExplicitSolveUpdate(mHighOrderUpdate, rk_residuals_ho, DeltaTime, rk_weights.begin(), rk_weights.end(), high_order_max_iteration);
441 CalculateAntidiffusiveEdgeContributions(DeltaTime);
444 EvaluateLimiter(DeltaTime);
447 IndexPartition<IndexType>(mAuxSize).for_each([
this](
IndexType i){
448 mSolutionOld[
i] = mSolution[
i];
452 auto GetButcherTableauVariant()
454 if (mTimeSchemeName ==
"forward_euler") {
456 }
else if (mTimeSchemeName ==
"midpoint_method") {
458 }
else if (mTimeSchemeName ==
"RK3-TVD") {
460 }
else if (mTimeSchemeName ==
"RK4") {
463 KRATOS_ERROR <<
"Butcher tableau cannot be found for time scheme '" << mTimeSchemeName <<
"'. Available options are 'forward_euler','midpoint_method','RK3-TVD' and 'RK4'." << std::endl;
467 template<
class TSolveCoeffsIterType>
468 void ExplicitSolveSolution(
469 std::vector<double>& rSolution,
470 const std::vector<std::vector<double>>& rResiduals,
471 const double DeltaTime,
472 const TSolveCoeffsIterType& rSolveCoeffBegin,
473 const TSolveCoeffsIterType& rSolveCoeffEnd,
476 auto solution_updater = [&](std::vector<double>& rSolution,
const IndexType NodeId,
const double UpdateValue)
477 { rSolution[NodeId] = mSolutionOld[NodeId] + UpdateValue; };
478 ExplicitSolve(rSolution, rResiduals, DeltaTime, rSolveCoeffBegin, rSolveCoeffEnd, solution_updater, MaxIteration);
481 template<
class TSolveCoeffsIterType>
482 void ExplicitSolveUpdate(
483 std::vector<double>& rUpdate,
484 const std::vector<std::vector<double>>& rResiduals,
485 const double DeltaTime,
486 const TSolveCoeffsIterType& rSolveCoeffBegin,
487 const TSolveCoeffsIterType& rSolveCoeffEnd,
490 auto solution_updater = [&](std::vector<double> &rUpdate,
const IndexType NodeId,
const double UpdateValue)
491 { rUpdate[NodeId] = UpdateValue; };
492 ExplicitSolve(rUpdate, rResiduals, DeltaTime, rSolveCoeffBegin, rSolveCoeffEnd, solution_updater, MaxIteration);
495 template<
class TSolveCoeffsIterType>
497 std::vector<double>& rSolution,
498 const std::vector<std::vector<double>>& rResiduals,
499 const double DeltaTime,
500 const TSolveCoeffsIterType& rSolveCoeffBegin,
501 const TSolveCoeffsIterType& rSolveCoeffEnd,
502 const std::function<
void(std::vector<double>&,
const IndexType,
const double)>& rUpdater,
505 if (MaxIteration == 1) {
509 const auto it_node = mpModelPart->
NodesBegin() + iNode;
510 const IndexType i_node_id = it_node->Id();
514 const bool is_fixed = it_node->IsFixed(*mpConvectedVar);
515 const double update = is_fixed ? 0.0 : (DeltaTime / M_l) * std::inner_product(rSolveCoeffBegin, rSolveCoeffEnd, rResiduals[i_node_id].begin(), 0.0);
516 rUpdater(rSolution, i_node_id, update);
520 const auto &r_row_indices = mpEdgeDataStructure->
GetRowIndices();
521 const auto &r_col_indices = mpEdgeDataStructure->
GetColIndices();
522 SizeType aux_n_rows = r_row_indices.size() - 1;
526 std::vector<double> aux_update(mAuxSize);
527 std::vector<double> galerkin_residual(mAuxSize);
530 const auto it_node = mpModelPart->
NodesBegin() + iNode;
531 const IndexType i_node_id = it_node->Id();
534 if (it_node->IsFixed(*mpConvectedVar)) {
535 aux_update[i_node_id] = 0.0;
537 const double M_l = mpEdgeDataStructure->GetLumpedMassMatrixDiagonal(i_node_id);
538 const double i_node_res = std::inner_product(rSolveCoeffBegin, rSolveCoeffEnd, rResiduals[i_node_id].begin(), 0.0);
539 galerkin_residual[i_node_id] = i_node_res;
540 aux_update[i_node_id] = (DeltaTime / M_l) * i_node_res;
545 std::vector<double> it_residual(mAuxSize);
548 IndexPartition<IndexType>(mAuxSize).for_each([&](
IndexType i){
549 it_residual[
i] = galerkin_residual[
i];
553 IndexPartition<IndexType>(aux_n_rows).for_each([&](
IndexType iRow){
555 const auto it_row = r_row_indices.begin() + iRow;
557 const SizeType n_cols = *(it_row+1) - i_col_index;
562 const double delta_u_h_i = aux_update[iRow];
565 const auto i_col_begin = r_col_indices.begin() + i_col_index;
566 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
568 IndexType j_node_id = *(i_col_begin + j_node);
569 const double delta_u_h_j = aux_update[j_node_id];
572 const auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iRow, j_node_id);
573 const double Mc_ij = r_ij_edge_data.GetOffDiagonalConsistentMass();
574 const double res_edge_i = Mc_ij * (delta_u_h_i - delta_u_h_j) / DeltaTime;
575 const double res_edge_j = Mc_ij * (delta_u_h_j - delta_u_h_i) / DeltaTime;
578 AtomicAdd(it_residual[iRow], res_edge_i);
579 AtomicAdd(it_residual[j_node_id], res_edge_j);
587 const auto it_node = mpModelPart->
NodesBegin() + iNode;
588 const IndexType i_node_id = it_node->Id();
591 if (it_node->IsFixed(*mpConvectedVar)) {
592 aux_update[i_node_id] = 0.0;
594 const double M_l = mpEdgeDataStructure->GetLumpedMassMatrixDiagonal(i_node_id);
595 aux_update[i_node_id] = (DeltaTime / M_l) * it_residual[i_node_id];
602 const auto it_node = mpModelPart->
NodesBegin() + iNode;
603 if (!it_node->IsFixed(*mpConvectedVar)) {
604 const IndexType i_node_id = it_node->Id();
605 rUpdater(rSolution, i_node_id, aux_update[i_node_id]);
611 void CalculateResidual(
612 std::vector<std::vector<double>>& rResiduals,
613 const std::vector<double>& rSolutionVector,
615 const double DiffusionConstant,
616 const double DeltaTime)
619 const auto &r_row_indices = mpEdgeDataStructure->
GetRowIndices();
620 const auto &r_col_indices = mpEdgeDataStructure->
GetColIndices();
621 SizeType aux_n_rows = r_row_indices.size() - 1;
626 array_1d<double, TDim> F_i;
627 array_1d<double, TDim> F_j;
628 array_1d<double, TDim> d_ij;
629 array_1d<double, TDim> b_ij;
630 array_1d<double, TDim> F_ij_num;
635 IndexPartition<IndexType>(aux_n_rows).for_each(AuxTLS(), [&](
IndexType iRow, AuxTLS& rTLS){
637 const auto it_row = r_row_indices.begin() + iRow;
639 const SizeType n_cols = *(it_row+1) - i_col_index;
644 auto& F_i = rTLS.F_i;
645 auto& F_j = rTLS.F_j;
646 auto& d_ij = rTLS.d_ij;
647 auto& b_ij = rTLS.b_ij;
648 auto& F_ij_num = rTLS.F_ij_num;
652 const double u_i = rSolutionVector[iRow];
653 const auto& r_i_vel = mConvectionValues[iRow];
657 F_i[
d] = u_i * r_i_vel[
d];
661 const auto i_col_begin = r_col_indices.begin() + i_col_index;
662 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
664 IndexType j_node_id = *(i_col_begin + j_node);
665 const double u_j = rSolutionVector[j_node_id];
666 const auto& r_j_vel = mConvectionValues[j_node_id];
670 F_j[
d] = u_j * r_j_vel[
d];
674 const auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iRow, j_node_id);
675 const auto& r_Ni_DNj = r_ij_edge_data.GetOffDiagonalConvective();
676 const auto& r_DNi_Nj = r_ij_edge_data.GetOffDiagonalConvectiveTranspose();
677 d_ij = 0.5 * (r_Ni_DNj - r_DNi_Nj);
680 D_ij += std::pow(d_ij[
d],2);
692 F_ij_num = F_i + F_j;
695 double res_edge_i =
inner_prod(-d_ij, F_ij_num);
696 double res_edge_j =
inner_prod(d_ij, F_ij_num);
699 if (r_ij_edge_data.IsBoundary()) {
701 const auto &r_N_N_normal = r_ij_edge_data.GetOffDiagonalConvectiveBoundary();
702 b_ij = 0.5 * r_N_N_normal;
705 const double res_edge_bd =
inner_prod(b_ij, F_ij_num);
706 res_edge_i -= res_edge_bd;
707 res_edge_j += res_edge_bd;
716 if (DiffusionConstant > 0.0) {
717 const double local_dt = CalculateEdgeLocalDeltaTime(r_ij_edge_data.GetLength(),
norm_2(r_i_vel),
norm_2(r_j_vel));
718 const double c_tau = mDiffusionConstant / local_dt;
719 const double Mc_ij = r_ij_edge_data.GetOffDiagonalConsistentMass();
720 const double ij_low_order_diff = c_tau * Mc_ij;
721 res_edge_i += ij_low_order_diff * (u_j - u_i);
722 res_edge_j += ij_low_order_diff * (u_i - u_j);
726 AtomicAdd(rResiduals[iRow][ResidualColumn], res_edge_i);
727 AtomicAdd(rResiduals[j_node_id][ResidualColumn], res_edge_j);
733 IndexPartition<IndexType>(mpModelPart->
NumberOfNodes()).for_each(array_1d<double,TDim>(), [&](
IndexType iNode, array_1d<double,TDim>& rTLS){
735 const auto it_node = mpModelPart->
NodesBegin() + iNode;
736 const IndexType i_node_id = it_node->Id();
740 double aux_res = 0.0;
741 const double u_i = rSolutionVector[i_node_id];
742 const auto &r_i_vel = mConvectionValues[i_node_id];
744 aux_res += u_i * r_i_vel[
d] * rTLS[
d];
746 rResiduals[i_node_id][ResidualColumn] -= aux_res;
750 void CalculateAntidiffusiveEdgeContributions(
const double DeltaTime)
754 <<
"Antidiffusive edge contributions cannot be computed as provided time increment " << DeltaTime <<
"is close to zero." << std::endl;
757 const auto &r_row_indices = mpEdgeDataStructure->
GetRowIndices();
758 const auto &r_col_indices = mpEdgeDataStructure->
GetColIndices();
759 SizeType aux_n_rows = r_row_indices.size() - 1;
762 IndexPartition<IndexType>(aux_n_rows).for_each([&](
IndexType iRow){
764 const auto it_row = r_row_indices.begin() + iRow;
766 const SizeType n_cols = *(it_row+1) - i_col_index;
771 const double u_i = mSolution[iRow];
772 const double du_h_i = mHighOrderUpdate[iRow];
773 const auto& r_i_vel = mConvectionValues[iRow];
776 const auto i_col_begin = r_col_indices.begin() + i_col_index;
777 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
779 IndexType j_node_id = *(i_col_begin + j_node);
780 const double u_j = mSolution[j_node_id];
781 const double du_h_j = mHighOrderUpdate[j_node_id];
782 const auto& r_j_vel = mConvectionValues[j_node_id];
785 auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iRow, j_node_id);
786 const double local_dt = CalculateEdgeLocalDeltaTime(r_ij_edge_data.GetLength(),
norm_2(r_i_vel),
norm_2(r_j_vel));
787 const double c_tau = mDiffusionConstant * DeltaTime / local_dt;
788 const double Mc_ij = r_ij_edge_data.GetOffDiagonalConsistentMass();
789 const double AEC_ij = Mc_ij * (c_tau * (u_i - u_j) + (du_h_i - du_h_j)) / DeltaTime;
793 if (AEC_ij * (u_j - u_i) > 0.0) {
794 r_ij_edge_data.SetAntidiffusiveEdgeContribution(0.0);
796 r_ij_edge_data.SetAntidiffusiveEdgeContribution(AEC_ij);
803 void EvaluateLimiter(
const double DeltaTime)
806 std::vector<double> P_min(mAuxSize, 0.0);
807 std::vector<double> P_max(mAuxSize, 0.0);
808 std::vector<double> Q_min(mAuxSize, 0.0);
809 std::vector<double> Q_max(mAuxSize, 0.0);
812 const auto &r_row_indices = mpEdgeDataStructure->
GetRowIndices();
813 const auto &r_col_indices = mpEdgeDataStructure->
GetColIndices();
814 SizeType aux_n_rows = r_row_indices.size() - 1;
817 IndexPartition<IndexType>(aux_n_rows).for_each([&](
IndexType iRow){
819 const auto it_row = r_row_indices.begin() + iRow;
821 const SizeType n_cols = *(it_row+1) - i_col_index;
826 const double u_i = mSolution[iRow];
831 const auto i_col_begin = r_col_indices.begin() + i_col_index;
832 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
834 IndexType j_node_id = *(i_col_begin + j_node);
835 const double u_j = mSolution[j_node_id];
840 const auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iRow, j_node_id);
841 const double AEC_ij = r_ij_edge_data.GetAntidiffusiveEdgeContribution();
850 const double aux_val_i = M_l_i * (u_j - u_i) / DeltaTime;
851 const double aux_val_j = M_l_j * (u_i - u_j) / DeltaTime;
852 Q_min[iRow] =
std::min(Q_min[iRow], aux_val_i);
853 Q_max[iRow] =
std::max(Q_max[iRow], aux_val_i);
854 Q_min[j_node_id] =
std::min(Q_min[j_node_id], aux_val_j);
855 Q_max[j_node_id] =
std::max(Q_max[j_node_id], aux_val_j);
861 const double zero_tol = 1.0e-12;
862 std::vector<double> R_min(mAuxSize);
863 std::vector<double> R_max(mAuxSize);
864 IndexPartition<IndexType>(mAuxSize).for_each([&](
IndexType i){
867 const double P_max_i = std::abs(P_max[
i]) < zero_tol ? zero_tol : P_max[
i];
872 const double P_min_i = std::abs(P_min[
i]) < zero_tol ? -zero_tol : P_min[
i];
877 std::vector<double> antidiff_assembly(mAuxSize, 0.0);
878 IndexPartition<IndexType>(aux_n_rows).for_each([&](
IndexType iRow){
880 const auto it_row = r_row_indices.begin() + iRow;
882 const SizeType n_cols = *(it_row+1) - i_col_index;
887 const auto i_col_begin = r_col_indices.begin() + i_col_index;
888 for (
IndexType j_node = 0; j_node < n_cols; ++j_node) {
890 IndexType j_node_id = *(i_col_begin + j_node);
893 const auto& r_ij_edge_data = mpEdgeDataStructure->
GetEdgeData(iRow, j_node_id);
894 const double AEC_ij = r_ij_edge_data.GetAntidiffusiveEdgeContribution();
897 const double alpha_ij = AEC_ij > 0.0 ?
std::min(R_max[iRow], R_min[j_node_id]) :
std::
min(R_min[iRow], R_max[j_node_id]);
898 KRATOS_ERROR_IF(alpha_ij < 0.0 || alpha_ij > 1.0) <<
"Correction factor is " << alpha_ij <<
" for edge " << iRow <<
"-" << j_node_id << std::endl;
901 const double aux = alpha_ij * AEC_ij;
903 AtomicAdd(antidiff_assembly[j_node_id], -aux);
912 const auto it_node = mpModelPart->
NodesBegin() + iNode;
913 const IndexType i_node_id = it_node->Id();
917 const double solve_coeff = DeltaTime / M_l;
918 mSolution[i_node_id] += solve_coeff * antidiff_assembly[i_node_id];
946 template<
unsigned int TDim>
948 std::istream& rIStream,
952 template<
unsigned int TDim>
954 std::ostream& rOStream,
958 rOStream << std::endl;
virtual const DataCommunicator & GetDataCommunicator() const
Definition: communicator.cpp:340
Definition: edge_based_data_structure.h:52
const IndicesVectorType & GetRowIndices() const
Definition: edge_based_data_structure.h:253
const IndicesVectorType & GetColIndices() const
Definition: edge_based_data_structure.h:258
const BoundaryMassMatrixVectorType & GetBoundaryMassMatrixDiagonal() const
Definition: edge_based_data_structure.h:273
const MassMatrixVectorType & GetLumpedMassMatrixDiagonal() const
Definition: edge_based_data_structure.h:283
const EdgeDataVectorType & GetEdgeData() const
Definition: edge_based_data_structure.h:293
std::size_t IndexType
Definition: flags.h:74
Process to solve a pure convection problem using a Flux Corrected Transport scheme and an edge-based ...
Definition: flux_corrected_transport_convection_process.h:58
void Execute() override
Execute method is used to execute the Process algorithms.
Definition: flux_corrected_transport_convection_process.h:152
FluxCorrectedTransportConvectionProcess(FluxCorrectedTransportConvectionProcess const &rOther)=delete
Copy constructor.
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: flux_corrected_transport_convection_process.h:251
FluxCorrectedTransportConvectionProcess(Model &rModel, Parameters ThisParameters)
Definition: flux_corrected_transport_convection_process.h:80
KRATOS_CLASS_POINTER_DEFINITION(FluxCorrectedTransportConvectionProcess)
Pointer definition of FluxCorrectedTransportConvectionProcess.
std::variant< ButcherTableauForwardEuler, ButcherTableauMidPointMethod, ButcherTableauRK3TVD, ButcherTableauRK4 > VariantTableauType
Definition: flux_corrected_transport_convection_process.h:67
void ExecuteInitialize() override
This function is designed for being called at the beginning of the computations right after reading t...
Definition: flux_corrected_transport_convection_process.h:125
std::size_t SizeType
Definition: flux_corrected_transport_convection_process.h:63
const Parameters GetDefaultParameters() const override
This method provides the defaults parameters to avoid conflicts between the different constructors.
Definition: flux_corrected_transport_convection_process.h:216
FluxCorrectedTransportConvectionProcess & operator=(FluxCorrectedTransportConvectionProcess const &rOther)=delete
Assignment operator.
std::size_t IndexType
Definition: flux_corrected_transport_convection_process.h:65
void Clear() override
This method clears the assignation of the conditions.
Definition: flux_corrected_transport_convection_process.h:206
std::string Info() const override
Turn back information as a string.
Definition: flux_corrected_transport_convection_process.h:245
~FluxCorrectedTransportConvectionProcess()=default
Destructor.
void PrintData(std::ostream &rOStream) const override
Print object's data.
Definition: flux_corrected_transport_convection_process.h:257
This class is useful for index iteration over containers.
Definition: parallel_utilities.h:451
void for_each(TUnaryFunction &&f)
Definition: parallel_utilities.h:514
KratosComponents class encapsulates a lookup table for a family of classes in a generic way.
Definition: kratos_components.h:49
Definition: reduction_utilities.h:190
This class aims to manage different model parts across multi-physics simulations.
Definition: model.h:60
ModelPart & GetModelPart(const std::string &rFullModelPartName)
This method returns a model part given a certain name.
Definition: model.cpp:107
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
Communicator & GetCommunicator()
Definition: model_part.h:1821
NodeIterator NodesBegin(IndexType ThisIndex=0)
Definition: model_part.h:487
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
SizeType NumberOfNodes(IndexType ThisIndex=0) const
Definition: model_part.h:341
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
The base class for all processes in Kratos.
Definition: process.h:49
ProcessInfo & GetPreviousTimeStepInfo(IndexType StepsBefore=1)
Definition: process_info.h:187
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_ERROR_IF(conditional)
Definition: exception.h:162
#define KRATOS_INFO_IF(label, conditional)
Definition: logger.h:251
dt
Definition: DEM_benchmarks.py:173
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
void AtomicAdd(TDataType &target, const TDataType &value)
Definition: atomic_utilities.h:55
void block_for_each(TIterator itBegin, TIterator itEnd, TFunction &&rFunction)
Execute a functor on all items of a range in parallel.
Definition: parallel_utilities.h:299
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::size_t SizeType
The definition of the size type.
Definition: mortar_classes.h:43
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
int n_steps
Definition: bombardelli_test.py:27
int step
Definition: face_heat.py:88
int n_nodes
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:15
int d
Definition: ode_solve.py:397
namespace
Definition: array_1d.h:793
integer i
Definition: TensorModule.f:17