13 #if !defined(KRATOS_ALGEBRAIC_FLUX_CORRECTED_SCALAR_STEADY_SCHEME)
14 #define KRATOS_ALGEBRAIC_FLUX_CORRECTED_SCALAR_STEADY_SCHEME
49 template <
class TSparseSpace,
class TDenseSpace>
75 const double RelaxationFactor,
76 const Flags BoundaryFlags)
78 mRelaxationFactor(RelaxationFactor),
79 mBoundaryFlags(BoundaryFlags),
82 KRATOS_INFO(
"AlgebraicFluxCorrectedSteadyScalarScheme")
83 <<
" Using residual based algebraic flux corrected scheme with "
86 << std::scientific << mRelaxationFactor <<
"\n";
88 mpDofUpdater = Kratos::make_unique<DofUpdaterType>(mRelaxationFactor);
92 const double RelaxationFactor,
93 const Flags BoundaryFlags,
96 mRelaxationFactor(RelaxationFactor),
97 mBoundaryFlags(BoundaryFlags),
98 mrPeriodicIdVar(rPeriodicIdVar)
100 KRATOS_INFO(
"AlgebraicFluxCorrectedSteadyScalarScheme")
101 <<
" Using periodic residual based algebraic flux corrected scheme "
104 << std::scientific << mRelaxationFactor <<
"\n";
106 mpDofUpdater = Kratos::make_unique<DofUpdaterType>(mRelaxationFactor);
122 rNode.SetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX, 0.0);
123 rNode.SetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX, 0.0);
124 rNode.SetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT, 0.0);
125 rNode.SetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT, 0.0);
130 if (rCondition.Is(PERIODIC)) {
132 KRATOS_ERROR_IF(rCondition.GetGeometry().PointsNumber() != 2)
133 << this->Info() <<
" only supports two noded periodic conditions. Found "
134 << rCondition.Info() <<
" with "
135 << rCondition.GetGeometry().PointsNumber() <<
" nodes.\n";
137 const auto& r_node_0 = rCondition.GetGeometry()[0];
138 const std::size_t r_node_0_pair_id =
139 r_node_0.FastGetSolutionStepValue(mrPeriodicIdVar);
141 const auto& r_node_1 = rCondition.GetGeometry()[1];
142 const std::size_t r_node_1_pair_id =
143 r_node_1.FastGetSolutionStepValue(mrPeriodicIdVar);
145 KRATOS_ERROR_IF(r_node_0_pair_id != r_node_1.Id())
146 <<
"Periodic condition pair id mismatch in "
147 << mrPeriodicIdVar.Name() <<
". [ " << r_node_0_pair_id
148 <<
" != " << r_node_1.Id() <<
" ].\n";
150 KRATOS_ERROR_IF(r_node_1_pair_id != r_node_0.Id())
151 <<
"Periodic condition pair id mismatch in "
152 << mrPeriodicIdVar.Name() <<
". [ " << r_node_1_pair_id
153 <<
" != " << r_node_0.Id() <<
" ].\n";
159 const auto num_threads = OpenMPUtils::GetNumThreads();
161 mAntiDiffusiveFluxCoefficients.resize(
num_threads);
176 auto& r_nodes = rModelPart.
Nodes();
179 rNode.
GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX) = 0.0;
180 rNode.
GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX) = 0.0;
181 rNode.
GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = 0.0;
182 rNode.
GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = 0.0;
185 auto& r_elements = rModelPart.
Elements();
186 const int number_of_elements = r_elements.size();
192 Matrix left_hand_side, artificial_diffusion, aux_matrix;
194 std::vector<IndexType> equation_ids;
196 for (
int i = 0;
i < number_of_elements; ++
i) {
197 auto& r_element = *(r_elements.begin() +
i);
198 this->CalculateSystemMatrix<Element>(r_element, left_hand_side,
199 right_hand_side, aux_matrix,
200 r_current_process_info);
201 this->CalculateArtificialDiffusionMatrix(artificial_diffusion, left_hand_side);
202 r_element.EquationIdVector(equation_ids, r_current_process_info);
203 r_element.GetValuesVector(
values);
205 const int size = artificial_diffusion.size1();
212 auto& r_geometry = r_element.GetGeometry();
213 for (
int i = 0;
i < size; ++
i) {
214 for (
int j = 0;
j < size;
j++) {
216 const double f_ij = artificial_diffusion(
i,
j) *
219 if (left_hand_side(
j,
i) <= left_hand_side(
i,
j)) {
224 if (equation_ids[
i] < equation_ids[
j]) {
234 for (
int i = 0;
i < size; ++
i) {
235 auto& r_node = r_geometry[
i];
237 r_node.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX) += p_plus[
i];
238 r_node.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) += q_plus[
i];
239 r_node.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX) += p_minus[
i];
240 r_node.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) += q_minus[
i];
248 if (rCondition.Is(PERIODIC)) {
249 auto& r_node_0 = rCondition.GetGeometry()[0];
250 auto& r_node_1 = rCondition.GetGeometry()[1];
252 double p_plus = r_node_0.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX);
253 double q_plus = r_node_0.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
254 double p_minus = r_node_0.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX);
255 double q_minus = r_node_0.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
257 p_plus += r_node_1.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX);
258 q_plus += r_node_1.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
259 p_minus += r_node_1.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX);
260 q_minus += r_node_1.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
263 r_node_0.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX) = p_plus;
264 r_node_0.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = q_plus;
265 r_node_0.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX) = p_minus;
266 r_node_0.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = q_minus;
267 r_node_0.UnSetLock();
270 r_node_1.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX) = p_plus;
271 r_node_1.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = q_plus;
272 r_node_1.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX) = p_minus;
273 r_node_1.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT) = q_minus;
274 r_node_1.UnSetLock();
279 Communicator& r_communicator = rModelPart.GetCommunicator();
297 mpDofUpdater->UpdateDofs(rDofSet, rDx);
304 this->mpDofUpdater->Clear();
316 const auto k = OpenMPUtils::ThisThread();
318 this->CalculateSystemMatrix<Element>(rElement, rLHS_Contribution, rRHS_Contribution,
319 mAuxMatrix[
k], rCurrentProcessInfo);
322 this->CalculateArtificialDiffusionMatrix(mAuxMatrix[
k], rLHS_Contribution);
324 AddAntiDiffusiveFluxes(rRHS_Contribution, rLHS_Contribution, rElement,
326 noalias(rLHS_Contribution) += mAuxMatrix[
k];
329 noalias(rRHS_Contribution) -=
prod(rLHS_Contribution, mValues[
k]);
343 const auto k = OpenMPUtils::ThisThread();
345 this->CalculateSystemMatrix<Condition>(rCondition, rLHS_Contribution, rRHS_Contribution,
346 mAuxMatrix[
k], rCurrentProcessInfo);
360 const auto k = OpenMPUtils::ThisThread();
361 CalculateSystemContributions(rElement, mAuxMatrix[
k], rRHS_Contribution,
362 rEquationIdVector, rCurrentProcessInfo);
375 const auto k = OpenMPUtils::ThisThread();
376 CalculateSystemContributions(rCondition, mAuxMatrix[
k], rRHS_Contribution,
377 rEquationIdVector, rCurrentProcessInfo);
395 using DofUpdaterPointerType =
typename DofUpdaterType::UniquePointer;
397 DofUpdaterPointerType mpDofUpdater;
399 double mRelaxationFactor;
400 const Flags mBoundaryFlags;
403 std::vector<LocalSystemMatrixType> mAuxMatrix;
404 std::vector<LocalSystemMatrixType> mAntiDiffusiveFluxCoefficients;
405 std::vector<LocalSystemMatrixType> mAntiDiffusiveFlux;
406 std::vector<LocalSystemVectorType> mValues;
418 template <
typename TItem>
419 void CalculateSystemMatrix(
421 LocalSystemMatrixType& rLeftHandSide,
422 LocalSystemVectorType& rRightHandSide,
423 LocalSystemMatrixType& rAuxMatrix,
428 rItem.CalculateLocalSystem(rLeftHandSide, rRightHandSide, rCurrentProcessInfo);
429 rItem.CalculateLocalVelocityContribution(rAuxMatrix, rRightHandSide, rCurrentProcessInfo);
431 if (rAuxMatrix.size1() != 0) {
432 noalias(rLeftHandSide) += rAuxMatrix;
444 void CalculateArtificialDiffusionMatrix(
450 if (rOutput.size1() != size || rOutput.size2() != size) {
451 rOutput.resize(size, size,
false);
459 rOutput(
j,
i) = rOutput(
i,
j);
466 value -= rOutput(
i,
j);
468 rOutput(
i,
i) = value;
485 template <
typename TItem>
486 void AddAntiDiffusiveFluxes(
490 const Matrix& rArtificialDiffusion)
494 const auto k = OpenMPUtils::ThisThread();
495 const auto size = rRHS.size();
497 auto& r_anti_diffusive_flux_coefficients = mAntiDiffusiveFluxCoefficients[
k];
498 auto& r_anti_diffusive_flux = mAntiDiffusiveFlux[
k];
499 auto& r_values = mValues[
k];
501 rItem.GetValuesVector(r_values);
502 if (r_anti_diffusive_flux_coefficients.size1() != size ||
503 r_anti_diffusive_flux_coefficients.size2() != size) {
504 r_anti_diffusive_flux_coefficients.resize(size, size,
false);
507 if (r_anti_diffusive_flux.size1() != size || r_anti_diffusive_flux.size2() != size) {
508 r_anti_diffusive_flux.resize(size, size,
false);
515 const auto& r_node_i = rItem.GetGeometry()[
i];
516 double r_plus_i{0.0}, r_minus_i{0.0};
517 CalculateAntiDiffusiveFluxR(r_plus_i, r_minus_i, r_node_i);
521 r_anti_diffusive_flux(
i,
j) =
522 rArtificialDiffusion(
i,
j) * (r_values[
j] - r_values[
i]);
524 if (rLHS(
j,
i) <= rLHS(
i,
j)) {
525 if (r_anti_diffusive_flux(
i,
j) > 0.0) {
526 r_anti_diffusive_flux_coefficients(
i,
j) = r_plus_i;
527 }
else if (r_anti_diffusive_flux(
i,
j) < 0.0) {
528 r_anti_diffusive_flux_coefficients(
i,
j) = r_minus_i;
530 r_anti_diffusive_flux_coefficients(
i,
j) = 1.0;
532 r_anti_diffusive_flux_coefficients(
j,
i) =
533 r_anti_diffusive_flux_coefficients(
i,
j);
541 rRHS[
i] += r_anti_diffusive_flux_coefficients(
i,
j) *
542 r_anti_diffusive_flux(
i,
j);
556 void CalculateAntiDiffusiveFluxR(
561 if (rNode.Is(mBoundaryFlags)) {
565 const double q_plus = rNode.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
566 const double p_plus = rNode.GetValue(AFC_POSITIVE_ANTI_DIFFUSIVE_FLUX);
567 const double q_minus = rNode.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX_LIMIT);
568 const double p_minus = rNode.GetValue(AFC_NEGATIVE_ANTI_DIFFUSIVE_FLUX);
572 rRPlus =
std::min(1.0, q_plus / p_plus);
577 rRMinus =
std::min(1.0, q_minus / p_minus);
Algebraic flux corrected scalar steady transport scheme.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:51
void InitializeNonLinIteration(ModelPart &rModelPart, TSystemMatrixType &A, TSystemVectorType &Dx, TSystemVectorType &b) override
unction to be called when it is needed to initialize an iteration. It is designed to be called at the...
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:168
void Initialize(ModelPart &rModelPart) override
This is the place to initialize the Scheme.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:115
void CalculateRHSContribution(Condition &rCondition, LocalSystemVectorType &rRHS_Contribution, Condition::EquationIdVectorType &rEquationIdVector, const ProcessInfo &rCurrentProcessInfo) override
Functions totally analogous to the precedent but applied to the "condition" objects.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:367
void Clear() override
Liberate internal storage.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:302
~AlgebraicFluxCorrectedSteadyScalarScheme() override=default
void CalculateSystemContributions(Condition &rCondition, LocalSystemMatrixType &rLHS_Contribution, LocalSystemVectorType &rRHS_Contribution, Element::EquationIdVectorType &rEquationIdVector, const ProcessInfo &rCurrentProcessInfo) override
Functions totally analogous to the precedent but applied to the "condition" objects.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:334
void Update(ModelPart &rModelPart, DofsArrayType &rDofSet, TSystemMatrixType &rA, TSystemVectorType &rDx, TSystemVectorType &rb) override
Performing the update of the solution.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:288
AlgebraicFluxCorrectedSteadyScalarScheme(const double RelaxationFactor, const Flags BoundaryFlags, const Variable< int > &rPeriodicIdVar)
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:91
void CalculateRHSContribution(Element &rElement, LocalSystemVectorType &rRHS_Contribution, Element::EquationIdVectorType &rEquationIdVector, const ProcessInfo &rCurrentProcessInfo) override
This function is designed to calculate just the RHS contribution.
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:352
KRATOS_CLASS_POINTER_DEFINITION(AlgebraicFluxCorrectedSteadyScalarScheme)
void CalculateSystemContributions(Element &rElement, LocalSystemMatrixType &rLHS_Contribution, LocalSystemVectorType &rRHS_Contribution, Element::EquationIdVectorType &rEquationIdVector, const ProcessInfo &rCurrentProcessInfo) override
This function is designed to be called in the builder and solver to introduce the selected time integ...
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:307
AlgebraicFluxCorrectedSteadyScalarScheme(const double RelaxationFactor, const Flags BoundaryFlags)
Definition: algebraic_flux_corrected_steady_scalar_scheme.h:74
The Commmunicator class manages communication for distributed ModelPart instances.
Definition: communicator.h:67
virtual bool AssembleNonHistoricalData(Variable< int > const &ThisVariable)
Definition: communicator.cpp:527
Base class for all Conditions.
Definition: condition.h:59
std::vector< std::size_t > EquationIdVectorType
Definition: condition.h:98
virtual void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const
Definition: condition.h:260
Base class for all Elements.
Definition: element.h:60
virtual void EquationIdVector(EquationIdVectorType &rResult, const ProcessInfo &rCurrentProcessInfo) const
Definition: element.h:258
virtual void GetValuesVector(Vector &values, int Step=0) const
Definition: element.h:300
std::vector< std::size_t > EquationIdVectorType
Definition: element.h:98
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
ConditionsContainerType & Conditions(IndexType ThisIndex=0)
Definition: model_part.h:1381
ProcessInfo & GetProcessInfo()
Definition: model_part.h:1746
ElementsContainerType & Elements(IndexType ThisIndex=0)
Definition: model_part.h:1189
NodesContainerType & Nodes(IndexType ThisIndex=0)
Definition: model_part.h:507
This class defines the node.
Definition: node.h:65
TVariableType::Type & GetValue(const TVariableType &rThisVariable)
Definition: node.h:466
A sorted associative container similar to an STL set, but uses a vector to store pointers to its data...
Definition: pointer_vector_set.h:72
ProcessInfo holds the current value of different solution parameters.
Definition: process_info.h:59
Utility class to update the values of degree of freedom (Dof) variables after solving the system.
Definition: relaxed_dof_updater.h:46
This class provides the implementation of the basic tasks that are needed by the solution strategy.
Definition: scheme.h:56
typename TSparseSpace::MatrixType TSystemMatrixType
Matrix type definition.
Definition: scheme.h:71
typename TSparseSpace::VectorType TSystemVectorType
Vector type definition.
Definition: scheme.h:74
typename TDenseSpace::VectorType LocalSystemVectorType
Local system vector type definition.
Definition: scheme.h:80
virtual void Initialize(ModelPart &rModelPart)
This is the place to initialize the Scheme.
Definition: scheme.h:168
ModelPart::DofsArrayType DofsArrayType
DoF array type definition.
Definition: scheme.h:86
typename TDenseSpace::MatrixType LocalSystemMatrixType
Local system matrix type definition.
Definition: scheme.h:77
Variable class contains all information needed to store and retrive data from a data container.
Definition: variable.h:63
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_INFO(label)
Definition: logger.h:250
std::size_t IndexType
Definition: binary_expression.cpp:25
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
KratosZeroVector< double > ZeroVector
Definition: amatrix_interface.h:561
Internals::Matrix< double, AMatrix::dynamic, 1 > Vector
Definition: amatrix_interface.h:472
KratosZeroMatrix< double > ZeroMatrix
Definition: amatrix_interface.h:559
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
Node NodeType
The definition of the node.
Definition: tetrahedral_mesh_orientation_check.h:34
Internals::Matrix< double, AMatrix::dynamic, AMatrix::dynamic > Matrix
Definition: amatrix_interface.h:470
AMatrix::MatrixProductExpression< TExpression1Type, TExpression2Type > prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:568
T & noalias(T &TheMatrix)
Definition: amatrix_interface.h:484
REACTION_CHECK_STIFFNESS_FACTOR int
Definition: contact_structural_mechanics_application_variables.h:75
list values
Definition: bombardelli_test.py:42
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
def num_threads
Definition: script.py:75
A
Definition: sensitivityMatrix.py:70
integer i
Definition: TensorModule.f:17