diff --git a/applications/ConstitutiveLawsApplication/constitutive_laws_application_variables.h b/applications/ConstitutiveLawsApplication/constitutive_laws_application_variables.h index a222e75f485a..564beedb97b0 100644 --- a/applications/ConstitutiveLawsApplication/constitutive_laws_application_variables.h +++ b/applications/ConstitutiveLawsApplication/constitutive_laws_application_variables.h @@ -26,7 +26,8 @@ namespace Kratos { enum class SofteningType {Linear = 0, Exponential = 1, HardeningDamage = 2, CurveFittingDamage = 3}; - enum class TangentOperatorEstimation {Analytic = 0, FirstOrderPerturbation = 1, SecondOrderPerturbation = 2, Secant = 3, SecondOrderPerturbationV2 = 4, InitialStiffness = 5}; + enum class TangentOperatorEstimation {Analytic = 0, FirstOrderPerturbation = 1, SecondOrderPerturbation = 2, + Secant = 3, SecondOrderPerturbationV2 = 4, InitialStiffness = 5, OrthogonalSecant = 6}; ///@name Functions ///@{ diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_kinematic_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_kinematic_plasticity.h index 70ffc261346d..471526ea9688 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_kinematic_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_kinematic_plasticity.h @@ -243,7 +243,7 @@ class GenericConstitutiveLawIntegratorKinematicPlasticity const double Denominator ) { - rTangent = rElasticMatrix - outer_prod(Vector(prod(rElasticMatrix, rGFluxVector)), Vector(prod(rElasticMatrix, rFFluxVector))) * Denominator; + noalias(rTangent) = rElasticMatrix - outer_prod(Vector(prod(rElasticMatrix, rGFluxVector)), Vector(prod(rElasticMatrix, rFFluxVector))) * Denominator; } @@ -281,10 +281,10 @@ class GenericConstitutiveLawIntegratorKinematicPlasticity { BoundedArrayType deviator = ZeroVector(VoigtSize); BoundedArrayType h_capa = ZeroVector(VoigtSize); - double J2, tensile_indicator_factor, compression_indicator_factor, slope, hardening_parameter, equivalent_plastic_strain; + double J2, tensile_indicator_factor, compression_indicator_factor, slope, hardening_parameter, equivalent_plastic_strain, I1; YieldSurfaceType::CalculateEquivalentStress( rPredictiveStressVector, rStrainVector, rUniaxialStress, rValues); - const double I1 = rPredictiveStressVector[0] + rPredictiveStressVector[1] + rPredictiveStressVector[2]; + AdvancedConstitutiveLawUtilities::CalculateI1Invariant(rPredictiveStressVector, I1); AdvancedConstitutiveLawUtilities::CalculateJ2Invariant(rPredictiveStressVector, I1, deviator, J2); CalculateDerivativeYieldSurface(rPredictiveStressVector, deviator, J2, rYieldSurfaceDerivative, rValues); CalculateDerivativePlasticPotential(rPredictiveStressVector, deviator, J2, rDerivativePlasticPotential, rValues); diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_plasticity.h index 617dd005374b..4b7b0a4a9d0c 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/cl_integrators/generic_cl_integrator_plasticity.h @@ -245,10 +245,10 @@ class GenericConstitutiveLawIntegratorPlasticity { array_1d deviator = ZeroVector(VoigtSize); array_1d h_capa = ZeroVector(VoigtSize); - double J2, tensile_indicator_factor, compression_indicator_factor, slope, hardening_parameter, equivalent_plastic_strain; + double J2, tensile_indicator_factor, compression_indicator_factor, slope, hardening_parameter, equivalent_plastic_strain, I1; YieldSurfaceType::CalculateEquivalentStress( rPredictiveStressVector, rStrainVector, rUniaxialStress, rValues); - const double I1 = rPredictiveStressVector[0] + rPredictiveStressVector[1] + rPredictiveStressVector[2]; + AdvancedConstitutiveLawUtilities::CalculateI1Invariant(rPredictiveStressVector, I1); AdvancedConstitutiveLawUtilities::CalculateJ2Invariant(rPredictiveStressVector, I1, deviator, J2); CalculateFFluxVector(rPredictiveStressVector, deviator, J2, rFflux, rValues); CalculateGFluxVector(rPredictiveStressVector, deviator, J2, rGflux, rValues); @@ -278,7 +278,7 @@ class GenericConstitutiveLawIntegratorPlasticity const double Denominator ) { - rTangent = rElasticMatrix - outer_prod(Vector(prod(rElasticMatrix, rGFluxVector)), Vector(prod(rElasticMatrix, rFFluxVector))) * Denominator; + noalias(rTangent) = rElasticMatrix - outer_prod(Vector(prod(rElasticMatrix, rGFluxVector)), Vector(prod(rElasticMatrix, rFFluxVector))) * Denominator; } diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/plastic_potentials/von_mises_plastic_potential.h b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/plastic_potentials/von_mises_plastic_potential.h index c8dd1fd2f9f5..92ac37b574b2 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/plastic_potentials/von_mises_plastic_potential.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/plastic_potentials/von_mises_plastic_potential.h @@ -116,16 +116,10 @@ class VonMisesPlasticPotential ) { array_1d first_vector, second_vector, third_vector; - - AdvancedConstitutiveLawUtilities::CalculateFirstVector(first_vector); AdvancedConstitutiveLawUtilities::CalculateSecondVector(rDeviator, J2, second_vector); - AdvancedConstitutiveLawUtilities::CalculateThirdVector(rDeviator, J2, third_vector); - - const double c1 = 0.0; const double c2 = std::sqrt(3.0); - const double c3 = 0.0; - noalias(rGFlux) = c1 * first_vector + c2 * second_vector + c3 * third_vector; + noalias(rGFlux) = c2 * second_vector; } /** diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/yield_surfaces/drucker_prager_yield_surface.h b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/yield_surfaces/drucker_prager_yield_surface.h index cdb15d7ad466..24e59f14336f 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/yield_surfaces/drucker_prager_yield_surface.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/auxiliary_files/yield_surfaces/drucker_prager_yield_surface.h @@ -234,7 +234,7 @@ class DruckerPragerYieldSurface AdvancedConstitutiveLawUtilities::CalculateFirstVector(first_vector); AdvancedConstitutiveLawUtilities::CalculateSecondVector(rDeviator, J2, second_vector); - const double friction_angle = r_material_properties[FRICTION_ANGLE] * Globals::Pi / 180.0;; + const double friction_angle = r_material_properties[FRICTION_ANGLE] * Globals::Pi / 180.0; const double sin_phi = std::sin(friction_angle); const double Root3 = std::sqrt(3.0); diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.cpp b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.cpp index 0ae7a21c6407..aefd1c59e80e 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.cpp +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.cpp @@ -164,9 +164,7 @@ void GenericFiniteStrainIsotropicPlasticity:: noalias(r_integrated_stress_vector) = predictive_stress_vector; if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { - this->CalculateTangentTensor(rValues, ConstitutiveLaw::StressMeasure_Kirchhoff); - } else { - BaseType::CalculateElasticMatrix( r_constitutive_matrix, rValues); + this->CalculateTangentTensor(rValues, ConstitutiveLaw::StressMeasure_Kirchhoff, plastic_strain); } } } @@ -301,7 +299,8 @@ template void GenericFiniteStrainIsotropicPlasticity:: CalculateTangentTensor( ConstitutiveLaw::Parameters& rValues, - const ConstitutiveLaw::StressMeasure& rStressMeasure + const ConstitutiveLaw::StressMeasure& rStressMeasure, + const Vector& rPlasticStrain ) { const Properties& r_material_properties = rValues.GetMaterialProperties(); @@ -317,6 +316,10 @@ void GenericFiniteStrainIsotropicPlasticity:: } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbation) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, rStressMeasure, consider_perturbation_threshold, 2); + } else if (tangent_operator_estimation == TangentOperatorEstimation::Secant) { + const Vector num = prod(rValues.GetConstitutiveMatrix(), rPlasticStrain); + const double denom = inner_prod(rValues.GetStrainVector(), num); + noalias(rValues.GetConstitutiveMatrix()) -= outer_prod(num, num) / denom; } } diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.h index bd64f77de502..75c2b57f39eb 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_isotropic_plasticity.h @@ -315,7 +315,8 @@ class KRATOS_API(CONSTITUTIVE_LAWS_APPLICATION) GenericFiniteStrainIsotropicPlas */ void CalculateTangentTensor( ConstitutiveLaw::Parameters &rValues, - const ConstitutiveLaw::StressMeasure& rStressMeasure = ConstitutiveLaw::StressMeasure_Cauchy + const ConstitutiveLaw::StressMeasure& rStressMeasure, + const Vector& rPlasticStrain ); ///@} diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.cpp b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.cpp index cd098665d569..4b612f11c097 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.cpp +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.cpp @@ -170,9 +170,7 @@ void GenericFiniteStrainKinematicPlasticity:: noalias(r_integrated_stress_vector) = predictive_stress_vector; if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { - this->CalculateTangentTensor(rValues, ConstitutiveLaw::StressMeasure_Kirchhoff); - } else { - BaseType::CalculateElasticMatrix( r_constitutive_matrix, rValues); + this->CalculateTangentTensor(rValues, ConstitutiveLaw::StressMeasure_Kirchhoff, plastic_strain); } } } @@ -314,7 +312,8 @@ template void GenericFiniteStrainKinematicPlasticity:: CalculateTangentTensor( ConstitutiveLaw::Parameters& rValues, - const ConstitutiveLaw::StressMeasure& rStressMeasure + const ConstitutiveLaw::StressMeasure& rStressMeasure, + const Vector& rPlasticStrain ) { const Properties& r_material_properties = rValues.GetMaterialProperties(); @@ -330,6 +329,10 @@ void GenericFiniteStrainKinematicPlasticity:: } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbation) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 2); + } else if (tangent_operator_estimation == TangentOperatorEstimation::Secant) { + const Vector num = prod(rValues.GetConstitutiveMatrix(), rPlasticStrain); + const double denom = inner_prod(rValues.GetStrainVector(), num); + noalias(rValues.GetConstitutiveMatrix()) -= outer_prod(num, num) / denom; } } diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.h index b2ae6950bd9d..f4eca1c59b17 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/finite_strains/plasticity/generic_finite_strain_kinematic_plasticity.h @@ -315,7 +315,8 @@ class KRATOS_API(CONSTITUTIVE_LAWS_APPLICATION) GenericFiniteStrainKinematicPlas */ void CalculateTangentTensor( ConstitutiveLaw::Parameters &rValues, - const ConstitutiveLaw::StressMeasure& rStressMeasure = ConstitutiveLaw::StressMeasure_Cauchy + const ConstitutiveLaw::StressMeasure& rStressMeasure, + const Vector& rPlasticStrain ); ///@} diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/damage/generic_small_strain_isotropic_damage.cpp b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/damage/generic_small_strain_isotropic_damage.cpp index 8b549da52996..d77c135ae059 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/damage/generic_small_strain_isotropic_damage.cpp +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/damage/generic_small_strain_isotropic_damage.cpp @@ -129,6 +129,7 @@ void GenericSmallStrainIsotropicDamage::CalculateMateri noalias(r_integrated_stress_vector) = predictive_stress_vector; if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { + r_constitutive_matrix *= (1.0 - damage); this->CalculateTangentTensor(rValues); } } @@ -163,7 +164,7 @@ void GenericSmallStrainIsotropicDamage::CalculateTangen // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 2); } else if (tangent_operator_estimation == TangentOperatorEstimation::Secant) { - rValues.GetConstitutiveMatrix() *= (1.0 - mDamage); + return; } else if (tangent_operator_estimation == TangentOperatorEstimation::InitialStiffness) { return; } diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.cpp b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.cpp index 32b21a9c5c58..058723fa41f7 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.cpp +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.cpp @@ -114,8 +114,8 @@ void GenericSmallStrainIsotropicPlasticity::CalculateMa this->template AddInitialStrainVectorContribution(r_strain_vector); // We compute the stress or the constitutive matrix - if (r_constitutive_law_options.Is( ConstitutiveLaw::COMPUTE_STRESS) || - r_constitutive_law_options.Is( ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { + if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_STRESS) || + r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { // We get some variables double threshold = this->GetThreshold(); @@ -167,9 +167,7 @@ void GenericSmallStrainIsotropicPlasticity::CalculateMa noalias(r_integrated_stress_vector) = predictive_stress_vector; if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { - this->CalculateTangentTensor(rValues); // this modifies the ConstitutiveMatrix - } else { - BaseType::CalculateElasticMatrix( r_constitutive_matrix, rValues); + this->CalculateTangentTensor(rValues, plastic_strain); // this modifies the ConstitutiveMatrix } } } @@ -180,7 +178,9 @@ void GenericSmallStrainIsotropicPlasticity::CalculateMa /***********************************************************************************/ template -void GenericSmallStrainIsotropicPlasticity::CalculateTangentTensor(ConstitutiveLaw::Parameters& rValues) +void GenericSmallStrainIsotropicPlasticity::CalculateTangentTensor( + ConstitutiveLaw::Parameters& rValues, + const Vector& rPlasticStrain) { const Properties& r_material_properties = rValues.GetMaterialProperties(); @@ -195,11 +195,17 @@ void GenericSmallStrainIsotropicPlasticity::CalculateTa } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbation) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 2); + } else if (tangent_operator_estimation == TangentOperatorEstimation::Secant) { + const Vector num = prod(rValues.GetConstitutiveMatrix(), rPlasticStrain); + const double denom = inner_prod(rValues.GetStrainVector(), num); + noalias(rValues.GetConstitutiveMatrix()) -= outer_prod(num, num) / denom; } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbationV2) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 4); - } else if (tangent_operator_estimation == TangentOperatorEstimation::InitialStiffness) { - BaseType::CalculateElasticMatrix( rValues.GetConstitutiveMatrix(), rValues); + } else if (tangent_operator_estimation == TangentOperatorEstimation::InitialStiffness) { + BaseType::CalculateElasticMatrix(rValues.GetConstitutiveMatrix(), rValues); + } else if (tangent_operator_estimation == TangentOperatorEstimation::OrthogonalSecant) { + TangentOperatorCalculatorUtility::CalculateOrthogonalSecantTensor(rValues); } } @@ -358,7 +364,6 @@ void GenericSmallStrainIsotropicPlasticity::FinalizeMat plastic_dissipation, plastic_strain_increment, r_constitutive_matrix, plastic_strain, rValues, characteristic_length); - BaseType::CalculateElasticMatrix(r_constitutive_matrix, rValues); } mPlasticDissipation = plastic_dissipation; diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.h index 69b3508b53ce..dadc956019f2 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_isotropic_plasticity.h @@ -441,7 +441,9 @@ class KRATOS_API(CONSTITUTIVE_LAWS_APPLICATION) GenericSmallStrainIsotropicPlast * @brief This method computes the tangent tensor * @param rValues The constitutive law parameters and flags */ - void CalculateTangentTensor(ConstitutiveLaw::Parameters &rValues); + void CalculateTangentTensor( + ConstitutiveLaw::Parameters &rValues, + const Vector& rPlasticStrain); ///@} ///@name Private Access diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.cpp b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.cpp index 4ae7bbe19a31..d460d4156c6e 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.cpp +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.cpp @@ -179,7 +179,7 @@ void GenericSmallStrainKinematicPlasticity::CalculateMa noalias(r_integrated_stress_vector) = predictive_stress_vector; if (r_constitutive_law_options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)) { - this->CalculateTangentTensor(rValues); // this modifies the ConstitutiveMatrix + this->CalculateTangentTensor(rValues, plastic_strain); // this modifies the ConstitutiveMatrix } } } @@ -191,7 +191,8 @@ void GenericSmallStrainKinematicPlasticity::CalculateMa template void GenericSmallStrainKinematicPlasticity::CalculateTangentTensor( - ConstitutiveLaw::Parameters& rValues + ConstitutiveLaw::Parameters& rValues, + const Vector& rPlasticStrain ) { const Properties& r_material_properties = rValues.GetMaterialProperties(); @@ -207,9 +208,17 @@ void GenericSmallStrainKinematicPlasticity::CalculateTa } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbation) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 2); + } else if (tangent_operator_estimation == TangentOperatorEstimation::Secant) { + const Vector num = prod(rValues.GetConstitutiveMatrix(), rPlasticStrain); + const double denom = inner_prod(rValues.GetStrainVector(), num); + noalias(rValues.GetConstitutiveMatrix()) -= outer_prod(num, num) / denom; } else if (tangent_operator_estimation == TangentOperatorEstimation::SecondOrderPerturbationV2) { // Calculates the Tangent Constitutive Tensor by perturbation (second order) TangentOperatorCalculatorUtility::CalculateTangentTensor(rValues, this, ConstitutiveLaw::StressMeasure_Cauchy, consider_perturbation_threshold, 4); + } else if (tangent_operator_estimation == TangentOperatorEstimation::InitialStiffness) { + BaseType::CalculateElasticMatrix(rValues.GetConstitutiveMatrix(), rValues); + } else if (tangent_operator_estimation == TangentOperatorEstimation::OrthogonalSecant) { + TangentOperatorCalculatorUtility::CalculateOrthogonalSecantTensor(rValues); } } diff --git a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.h b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.h index 09f3e4aca520..fdf4aa4b53bb 100644 --- a/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.h +++ b/applications/ConstitutiveLawsApplication/custom_constitutive/small_strains/plasticity/generic_small_strain_kinematic_plasticity.h @@ -430,7 +430,9 @@ class KRATOS_API(CONSTITUTIVE_LAWS_APPLICATION) GenericSmallStrainKinematicPlast * @brief This method computes the tangent tensor * @param rValues The constitutive law parameters and flags */ - void CalculateTangentTensor(ConstitutiveLaw::Parameters &rValues); + void CalculateTangentTensor( + ConstitutiveLaw::Parameters &rValues, + const Vector& rPlasticStrain); ///@} ///@name Private Access diff --git a/applications/ConstitutiveLawsApplication/custom_utilities/advanced_constitutive_law_utilities.cpp b/applications/ConstitutiveLawsApplication/custom_utilities/advanced_constitutive_law_utilities.cpp index 3efda7e641da..0781dee6d771 100644 --- a/applications/ConstitutiveLawsApplication/custom_utilities/advanced_constitutive_law_utilities.cpp +++ b/applications/ConstitutiveLawsApplication/custom_utilities/advanced_constitutive_law_utilities.cpp @@ -137,10 +137,9 @@ void AdvancedConstitutiveLawUtilities::CalculateThirdVector( const double J2thirds = J2 / 3.0; if constexpr (Dimension == 2) { - rThirdVector[0] = rDeviator[1] * rDeviator[2] + J2thirds; - rThirdVector[1] = rDeviator[0] * rDeviator[2] + J2thirds; - rThirdVector[2] = rDeviator[0] * rDeviator[1] - std::pow(rDeviator[3], 2) + J2thirds; - rThirdVector[3] = -2.0 * rDeviator[3] * rDeviator[2]; + rThirdVector[0] = J2thirds; + rThirdVector[1] = J2thirds; + rThirdVector[2] = 0.0; // The szz should be added when 4-size is ready in plane strain } else { rThirdVector[0] = rDeviator[1] * rDeviator[2] - rDeviator[4] * rDeviator[4] + J2thirds; rThirdVector[1] = rDeviator[0] * rDeviator[2] - rDeviator[5] * rDeviator[5] + J2thirds; diff --git a/applications/ConstitutiveLawsApplication/custom_utilities/tangent_operator_calculator_utility.h b/applications/ConstitutiveLawsApplication/custom_utilities/tangent_operator_calculator_utility.h index 528794da17ac..2f47f4dff0d5 100644 --- a/applications/ConstitutiveLawsApplication/custom_utilities/tangent_operator_calculator_utility.h +++ b/applications/ConstitutiveLawsApplication/custom_utilities/tangent_operator_calculator_utility.h @@ -405,6 +405,38 @@ class TangentOperatorCalculatorUtility CalculateTangentTensorSmallDeformationNotProvidedStrain(rValues, pConstitutiveLaw, rStressMeasure, ConsiderPertubationThreshold, ApproximationOrder); } + /** + * @brief This method computes the secant tensor as dS/dE with respect to the origin + * @param rValues The properties of the CL + */ + static void CalculateSecantTensor(ConstitutiveLaw::Parameters& rValues) + { + const auto &r_strain = rValues.GetStrainVector(); + const auto &r_stress = rValues.GetStressVector(); + const SizeType strain_size = r_strain.size(); + auto &r_D = rValues.GetConstitutiveMatrix(); + + for (IndexType i = 0; i < strain_size; i++) + for (IndexType j = 0; j < strain_size; j++) + r_D(i, j) = r_stress[i] / r_strain[j]; + } + + /** + * @brief This method computes the secant tensor as dS/dE with respect to the origin + * @param rValues The properties of the CL + */ + static void CalculateOrthogonalSecantTensor(ConstitutiveLaw::Parameters& rValues) + { + const auto &r_strain = rValues.GetStrainVector(); + const auto &r_stress = rValues.GetStressVector(); + const SizeType strain_size = r_strain.size(); + auto &r_D = rValues.GetConstitutiveMatrix(); + + for (IndexType i = 0; i < strain_size; i++) + for (IndexType j = 0; j < strain_size; j++) + r_D(i, j) = -r_strain[j] / r_stress[i]; + } + protected: ///@name Protected static Member Variables ///@{ diff --git a/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.cpp b/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.cpp new file mode 100644 index 000000000000..6b88cef325a1 --- /dev/null +++ b/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.cpp @@ -0,0 +1,397 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ \. +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + +// System includes + + +// External includes + + +// Project includes +#include "includes/checks.h" + +// Application includes +#include "navier_stokes_p2_p1_continuous_wall_condition.h" +#include "wall_laws/linear_log_wall_law.h" +#include "wall_laws/navier_slip_wall_law.h" + +namespace Kratos +{ + +template +void NavierStokesP2P1ContinuousWallCondition::EquationIdVector( + EquationIdVectorType& rResult, + const ProcessInfo& rCurrentProcessInfo) const +{ + if (rResult.size() != LocalSize) { + rResult.resize(LocalSize, false); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_X, x_pos).EquationId(); + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Y, x_pos+1).EquationId(); + if constexpr (TDim == 3) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Z, x_pos+2).EquationId(); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(PRESSURE, p_pos).EquationId(); + } +} + +template +void NavierStokesP2P1ContinuousWallCondition::GetDofList( + DofsVectorType& rConditionDofList, + const ProcessInfo& rCurrentProcessInfo) const +{ + if (rConditionDofList.size() != LocalSize) { + rConditionDofList.resize(LocalSize); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rConditionDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_X, x_pos); + rConditionDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Y, x_pos+1); + if constexpr (TDim == 3) { + rConditionDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Z, x_pos+2); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rConditionDofList[local_index++] = r_geometry[i].pGetDof(PRESSURE, p_pos); + } +} + +template +void NavierStokesP2P1ContinuousWallCondition::CalculateLocalSystem( + MatrixType& rLeftHandSideMatrix, + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) +{ + KRATOS_TRY + + // Check (and resize) RHS and LHS arrays + if (rLeftHandSideMatrix.size1() != LocalSize) { + rLeftHandSideMatrix.resize(LocalSize, LocalSize, false); //false says not to preserve existing storage!! + } + if (rRightHandSideVector.size() != LocalSize) { + rRightHandSideVector.resize(LocalSize, false); //false says not to preserve existing storage!! + } + + // Struct to pass around the data + ConditionDataStruct data; + + // LHS and RHS contributions initialization + noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize,LocalSize); + noalias(rRightHandSideVector) = ZeroVector(LocalSize); + + // Compute condition unit normal vector + this->CalculateUnitNormal(data.UnitNormal); + + // Gauss point information + auto& r_geom = this->GetGeometry(); + const auto& r_integration_points = r_geom.IntegrationPoints(IntegrationMethod); + const SizeType num_gauss = r_integration_points.size(); + Vector gauss_pts_det = ZeroVector(num_gauss); + r_geom.DeterminantOfJacobian(gauss_pts_det, IntegrationMethod); + const MatrixType N_v_container = r_geom.ShapeFunctionsValues(IntegrationMethod); + + // Calculate viscous stress for the slip tangential correction + if (rCurrentProcessInfo.Has(SLIP_TANGENTIAL_CORRECTION_SWITCH)) { + if (this->Is(SLIP) && rCurrentProcessInfo.GetValue(SLIP_TANGENTIAL_CORRECTION_SWITCH)) { + KRATOS_WARNING("NavierStokesP2P1ContinuousWallCondition") + << "Slip tangential correction is not implemented. Please switch off 'slip_tangential_correction' in 'ApplySlipProcess'." << std::endl; + } + } + + // Loop on gauss points + for(IndexType i_gauss = 0; i_gauss< num_gauss; ++i_gauss) { + data.N_v = row(N_v_container, i_gauss); + data.Weight = gauss_pts_det[i_gauss] * r_integration_points[i_gauss].Weight(); + AddGaussPointRHSContribution(rRightHandSideVector, data, rCurrentProcessInfo); + } + + // Add the wall law contribution + constexpr SizeType n_wall_models = sizeof...(TWallModel); + static_assert(n_wall_models < 2, "More than one template wall model argument in 'NavierStokesWallCondition'."); + if (this->Is(WALL) && n_wall_models != 0) { + (AddWallModelLocalSystemCall(rLeftHandSideMatrix, rRightHandSideVector, rCurrentProcessInfo), ...); + } + + KRATOS_CATCH("") +} + +template +void NavierStokesP2P1ContinuousWallCondition::CalculateLeftHandSide( + MatrixType& rLeftHandSideMatrix, + const ProcessInfo& rCurrentProcessInfo) +{ + KRATOS_TRY + + // Check (and resize) LHS matrix + if (rLeftHandSideMatrix.size1() != LocalSize) { + rLeftHandSideMatrix.resize(LocalSize, LocalSize, false); //false says not to preserve existing storage!! + } + + // LHS contribution initialization + noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize, LocalSize); + + // Add the wall law contribution + constexpr SizeType n_wall_models = sizeof...(TWallModel); + static_assert(n_wall_models < 2, "More than one template wall model argument in 'NavierStokesWallCondition'."); + if (this->Is(WALL) && n_wall_models != 0) { + (AddWallModelLeftHandSideCall(rLeftHandSideMatrix, rCurrentProcessInfo), ...); + } + + KRATOS_CATCH("") +} + +template +void NavierStokesP2P1ContinuousWallCondition::CalculateRightHandSide( + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) +{ + KRATOS_TRY + + // Check (and resize) RHS vector + if (rRightHandSideVector.size() != LocalSize) { + rRightHandSideVector.resize(LocalSize, false); //false says not to preserve existing storage!! + } + + // Struct to pass around the data + ConditionDataStruct data; + + // RHS contribution initialization + noalias(rRightHandSideVector) = ZeroVector(LocalSize); + + // Compute condition unit normal vector + this->CalculateUnitNormal(data.UnitNormal); + + // Gauss point information + auto& r_geom = this->GetGeometry(); + const auto& r_integration_points = r_geom.IntegrationPoints(IntegrationMethod); + const SizeType num_gauss = r_integration_points.size(); + Vector gauss_pts_det = ZeroVector(num_gauss); + r_geom.DeterminantOfJacobian(gauss_pts_det, IntegrationMethod); + const MatrixType N_v_container = r_geom.ShapeFunctionsValues(IntegrationMethod); + + // Calculate viscous stress for the slip tangential correction + if (rCurrentProcessInfo.Has(SLIP_TANGENTIAL_CORRECTION_SWITCH)) { + if (this->Is(SLIP) && rCurrentProcessInfo.GetValue(SLIP_TANGENTIAL_CORRECTION_SWITCH)) { + KRATOS_WARNING("NavierStokesP2P1ContinuousWallCondition") + << "Slip tangential correction is not implemented. Please switch off 'slip_tangential_correction' in 'ApplySlipProcess'." << std::endl; + } + } + + // Loop on gauss points + for(IndexType i_gauss = 0; i_gauss< num_gauss; ++i_gauss) { + data.N_v = row(N_v_container, i_gauss); + data.Weight = gauss_pts_det[i_gauss] * r_integration_points[i_gauss].Weight(); + AddGaussPointRHSContribution(rRightHandSideVector, data, rCurrentProcessInfo); + } + + // Add the wall law contribution + constexpr SizeType n_wall_models = sizeof...(TWallModel); + static_assert(n_wall_models < 2, "More than one template wall model argument in 'NavierStokesWallCondition'."); + if (this->Is(WALL) && n_wall_models != 0) { + (AddWallModelRightHandSideCall(rRightHandSideVector, rCurrentProcessInfo), ...); + } + + KRATOS_CATCH("") +} + +template +int NavierStokesP2P1ContinuousWallCondition::Check(const ProcessInfo& rCurrentProcessInfo) const +{ + KRATOS_TRY; + int check = BaseType::Check(rCurrentProcessInfo); // Checks id > 0 and area > 0 + if (check != 0) { + return check; + } else { + // Check that geometry is coplanar (i.e. edges midpoint nodes are aligned) + // Note that though Kratos geometry supports non coplanar, this is assumed througout current implementation + const auto& r_geometry = this->GetGeometry(); + if constexpr (TDim == 2) { + array_1d vect_01 = r_geometry[1].Coordinates() - r_geometry[0].Coordinates(); + vect_01 /= norm_2(vect_01); + array_1d vect_02 = r_geometry[1].Coordinates() - r_geometry[0].Coordinates(); + vect_02 /= norm_2(vect_02); + KRATOS_CHECK_VECTOR_NEAR(vect_01, vect_02, 1.0e-12) + } else { + array_1d vect_01 = r_geometry[1].Coordinates() - r_geometry[0].Coordinates(); + vect_01 /= norm_2(vect_01); + array_1d vect_03 = r_geometry[3].Coordinates() - r_geometry[0].Coordinates(); + vect_03 /= norm_2(vect_03); + KRATOS_CHECK_VECTOR_NEAR(vect_01, vect_03, 1.0e-12) + array_1d vect_02 = r_geometry[2].Coordinates() - r_geometry[0].Coordinates(); + vect_02 /= norm_2(vect_02); + array_1d vect_05 = r_geometry[5].Coordinates() - r_geometry[0].Coordinates(); + vect_05 /= norm_2(vect_05); + KRATOS_CHECK_VECTOR_NEAR(vect_02, vect_05, 1.0e-12) + array_1d vect_12 = r_geometry[2].Coordinates() - r_geometry[1].Coordinates(); + vect_12 /= norm_2(vect_12); + array_1d vect_14 = r_geometry[4].Coordinates() - r_geometry[1].Coordinates(); + vect_14 /= norm_2(vect_14); + KRATOS_CHECK_VECTOR_NEAR(vect_12, vect_14, 1.0e-12) + } + + // Checks on nodes + // Check that the element's nodes contain all required SolutionStepData and Degrees Of Freedom variables + for (const auto& r_node : r_geometry) { + // Check variables + KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(VELOCITY, r_node) + KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(PRESSURE, r_node) + KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(MESH_VELOCITY, r_node) + KRATOS_CHECK_VARIABLE_IN_NODAL_DATA(EXTERNAL_PRESSURE, r_node) + // Check DOFs + KRATOS_CHECK_DOF_IN_NODE(VELOCITY_X, r_node) + KRATOS_CHECK_DOF_IN_NODE(VELOCITY_Y, r_node) + KRATOS_CHECK_DOF_IN_NODE(VELOCITY_Z, r_node) + KRATOS_CHECK_DOF_IN_NODE(PRESSURE, r_node) + } + + // Check that parents have been computed + // These are required to retrieve the material properties and the viscous stress + auto& parent_elements = this->GetValue(NEIGHBOUR_ELEMENTS); + KRATOS_ERROR_IF(parent_elements.size() > 1) << "Condition " << this->Id() << " was assigned more than one parent element." << std::endl; + KRATOS_ERROR_IF(parent_elements.size() == 0) << "Condition " << this->Id() << " has no parent element. Please execute 'check_and_prepare_model_process_fluid' process." << std::endl; + + // If provided, check wall law + constexpr SizeType n_wall_models = sizeof...(TWallModel); + static_assert(n_wall_models < 2, "More than one template wall model argument in 'NavierStokesWallCondition'."); + if constexpr (n_wall_models != 0) { + ((check = WallModelCheckCall(rCurrentProcessInfo)), ...); + } + + return check; + } + + KRATOS_CATCH(""); +} + +template +void NavierStokesP2P1ContinuousWallCondition::Calculate( + const Variable< array_1d >& rVariable, + array_1d& rOutput, + const ProcessInfo& rCurrentProcessInfo) +{ + rOutput = ZeroVector(3); + + if (rVariable == DRAG_FORCE) { + KRATOS_ERROR << "'DRAG_FORCE' variable is not implemented for NavierStokesP2P1ContinuousWallCondition" << TDim << "D." << std::endl; + } else { + BaseType::Calculate(rVariable, rOutput, rCurrentProcessInfo); + } +} + +template +void NavierStokesP2P1ContinuousWallCondition::CalculateUnitNormal(array_1d& rUnitNormal) +{ + const auto& r_geom = GetGeometry(); + if constexpr (TDim == 2) { + rUnitNormal[0] = r_geom[1].Y() - r_geom[0].Y(); + rUnitNormal[1] = - (r_geom[1].X() - r_geom[0].X()); + } else if constexpr (TDim == 3) { + array_1d v1,v2; + v1[0] = r_geom[1].X() - r_geom[0].X(); + v1[1] = r_geom[1].Y() - r_geom[0].Y(); + v1[2] = r_geom[1].Z() - r_geom[0].Z(); + + v2[0] = r_geom[2].X() - r_geom[0].X(); + v2[1] = r_geom[2].Y() - r_geom[0].Y(); + v2[2] = r_geom[2].Z() - r_geom[0].Z(); + + MathUtils::CrossProduct(rUnitNormal,v1,v2); + rUnitNormal *= 0.5; + } else { + KRATOS_ERROR << "'CalculateUnitNormal' is not implemented for current geometry." << std::endl; + } + rUnitNormal /= norm_2(rUnitNormal); +} + +template +void NavierStokesP2P1ContinuousWallCondition::AddGaussPointRHSContribution( + VectorType& rRHS, + const ConditionDataStruct& rData, + const ProcessInfo& rProcessInfo) +{ + // Gauss pt. Neumann BC contribution + this->ComputeRHSNeumannContribution(rRHS, rData); + + // Gauss pt. outlet inflow prevention contribution + if (rProcessInfo.Has(OUTLET_INFLOW_CONTRIBUTION_SWITCH)) { + if (this->Is(OUTLET) && rProcessInfo[OUTLET_INFLOW_CONTRIBUTION_SWITCH]){ + this->ComputeRHSOutletInflowContribution(rRHS, rData, rProcessInfo); + } + } +} + +template +void NavierStokesP2P1ContinuousWallCondition::ComputeRHSNeumannContribution( + VectorType& rRHS, + const ConditionDataStruct& rData) +{ + const auto& r_geom = this->GetGeometry(); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + const double p_ext = r_geom[i].FastGetSolutionStepValue(EXTERNAL_PRESSURE); + for (IndexType j = 0; j < VelocityNumNodes; ++j) { + for (IndexType d = 0; d < TDim; ++d) { + rRHS[j*TDim + d] -= rData.Weight * rData.N_v[j] * rData.N_v[i] * p_ext * rData.UnitNormal[d]; + } + } + } +} + +template +void NavierStokesP2P1ContinuousWallCondition::ComputeRHSOutletInflowContribution( + VectorType& rRHS, + const ConditionDataStruct& rData, + const ProcessInfo& rProcessInfo) +{ + // Get DENSITY from parent element properties + const auto& r_neighbours = this->GetValue(NEIGHBOUR_ELEMENTS); + const double rho = r_neighbours[0].GetProperties().GetValue(DENSITY); + + // Compute Gauss velocity norm and velocity projection + const auto& r_geom = this->GetGeometry(); + array_1d v_gauss = ZeroVector(3); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + const auto& r_v = r_geom[i].FastGetSolutionStepValue(VELOCITY); + v_gauss += rData.N_v[i] * r_v; + } + const double v_gauss_proj = std::inner_product(rData.UnitNormal.begin(), rData.UnitNormal.end(), v_gauss.begin(), 0.0); + const double v_gauss_squared_norm = std::pow(v_gauss[0],2) + std::pow(v_gauss[1],2) + std::pow(v_gauss[2],2); + + // Add outlet inflow prevention contribution + const double delta = 1.0e-2; + const double U_0 = rProcessInfo[CHARACTERISTIC_VELOCITY]; + const double S_0 = 0.5*(1.0 - std::tanh(v_gauss_proj/(U_0*delta))); + const double aux = rData.Weight * 0.5 * rho * v_gauss_squared_norm * S_0; + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + for (IndexType d = 0; d < TDim; ++d) { + rRHS[i*TDim + d] += aux * rData.N_v[i] * rData.UnitNormal[d]; + } + } +} + +template class NavierStokesP2P1ContinuousWallCondition<2>; +template class NavierStokesP2P1ContinuousWallCondition<3>; + +} // namespace Kratos diff --git a/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.h b/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.h new file mode 100644 index 000000000000..ebf2a0717e90 --- /dev/null +++ b/applications/FluidDynamicsApplication/custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.h @@ -0,0 +1,457 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ \. +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + +#pragma once + +// System includes +#include +#include + +// External includes + +// Project includes +#include "geometries/geometry_data.h" +#include "includes/define.h" +#include "includes/condition.h" +#include "includes/model_part.h" +#include "includes/serializer.h" +#include "includes/process_info.h" + +// Application includes +#include "fluid_dynamics_application_variables.h" +#include "navier_stokes_wall_condition.h" + +namespace Kratos +{ + +///@addtogroup FluidDynamicsApplication +///@{ + +///@name Kratos Globals +///@{ + +///@} +///@name Type Definitions +///@{ + +///@} +///@name Enum's +///@{ + +///@} +///@name Functions +///@{ + +///@} +///@name Kratos Classes +///@{ + +/** + * @brief Implements a wall condition for the Navier-Stokes (and Stokes) monolithic formulations + * This condition is intended to be used in combination with Navier-Stokes (or Stokes) P2-P1 (continuous + * pressure monolithic formulations. It supports the Neumann BC contribution as well as the addition of + * a wall law contribution through the TWallModel template argument. Such TWallModel must be a class + * implementing the wall model RHS and LHS Gauss point contributions (as example see @NavierSlipWallLaw). + * Current condition also has optional features that help numerical stability such as the outlet + * inflow energy correction or the spurious tangential velocity correction for pure slip boundaries. + * TODO: Implement the drag calculation (this requires implementing the viscous stress from the parent) + * TODO: Implement the slip boundaries spurious velocity correction (this requires implementing the viscous stress from the parent) + * TODO: Implement the wall contributions (this requires Lobatto quadratures and also I/O considerations if current ApplyWallLawProcess is used) + * @tparam TDim Number of dimensions + * @tparam TWallModel Optional class implementing a LHS and RHS wall contribution + */ +template +class KRATOS_API(FLUID_DYNAMICS_APPLICATION) NavierStokesP2P1ContinuousWallCondition : public Condition +{ +public: + + static_assert(sizeof...(TWallModel) == 0, "Wall models are not supported in 'NavierStokesP2P1ContinuousWallCondition' yet."); + + ///@name Type Definitions + ///@{ + + KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(NavierStokesP2P1ContinuousWallCondition); + + static constexpr std::size_t VoigtSize = 3*(TDim-1); + + static constexpr std::size_t VelocityNumNodes = TDim == 2 ? 3 : 6; + + static constexpr std::size_t PressureNumNodes = TDim == 2 ? 2 : 3; + + static constexpr std::size_t LocalSize = VelocityNumNodes*TDim + PressureNumNodes; + + static constexpr GeometryData::IntegrationMethod IntegrationMethod = GeometryData::IntegrationMethod::GI_GAUSS_3; + + using BaseType = Condition; + + using SizeType = typename BaseType::SizeType; + + using IndexType = typename BaseType::IndexType; + + using GeometryType = typename BaseType::GeometryType; + + using NodesArrayType = typename BaseType::NodesArrayType; + + using VectorType = typename BaseType::VectorType; + + using MatrixType = typename BaseType::MatrixType; + + using EquationIdVectorType = typename BaseType::EquationIdVectorType; + + using DofsVectorType = typename BaseType::DofsVectorType; + + struct ConditionDataStruct + { + double Weight; // Gauss point weight + array_1d UnitNormal; // Condition unit normal + array_1d N_v; // Gauss point velocity shape functions values + }; + + ///@} + ///@name Life Cycle + ///@{ + + /// Default constructor. + NavierStokesP2P1ContinuousWallCondition(IndexType NewId = 0) + : BaseType(NewId) + { + } + + /// Constructor using an array of nodes + NavierStokesP2P1ContinuousWallCondition( + IndexType NewId, + const NodesArrayType& ThisNodes) + : BaseType(NewId, ThisNodes) + { + } + + /// Constructor using Geometry + NavierStokesP2P1ContinuousWallCondition( + IndexType NewId, + typename GeometryType::Pointer pGeometry) + : BaseType(NewId, pGeometry) + { + } + + /// Constructor using Properties + NavierStokesP2P1ContinuousWallCondition( + IndexType NewId, + typename GeometryType::Pointer pGeometry, + Properties::Pointer pProperties) + : BaseType(NewId, pGeometry, pProperties) + { + } + + /// Copy constructor. + NavierStokesP2P1ContinuousWallCondition(NavierStokesP2P1ContinuousWallCondition const& rOther) + : BaseType(rOther) + { + } + + /// Destructor. + ~NavierStokesP2P1ContinuousWallCondition() override = default; + + ///@} + ///@name Operators + ///@{ + + /// Assignment operator + NavierStokesP2P1ContinuousWallCondition& operator=(NavierStokesP2P1ContinuousWallCondition const& rOther) + { + Condition::operator=(rOther); + return *this; + } + + ///@} + ///@name Operations + ///@{ + + Condition::Pointer Create( + IndexType NewId, + NodesArrayType const& ThisNodes, + typename Properties::Pointer pProperties) const override + { + return Kratos::make_intrusive(NewId, this->GetGeometry().Create(ThisNodes), pProperties); + } + + Condition::Pointer Create( + IndexType NewId, + typename GeometryType::Pointer pGeom, + typename Properties::Pointer pProperties) const override + { + return Kratos::make_intrusive(NewId, pGeom, pProperties); + } + + void CalculateLocalSystem( + MatrixType& rLeftHandSideMatrix, + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) override; + + void CalculateLeftHandSide( + MatrixType& rLeftHandSideMatrix, + const ProcessInfo& rCurrentProcessInfo) override; + + void CalculateRightHandSide( + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) override; + + int Check(const ProcessInfo& rCurrentProcessInfo) const override; + + void EquationIdVector( + EquationIdVectorType& rResult, + const ProcessInfo& rCurrentProcessInfo) const override; + + void GetDofList( + DofsVectorType& rConditionDofList, + const ProcessInfo& rCurrentProcessInfo) const override; + + void Calculate( + const Variable< array_1d>& rVariable, + array_1d& Output, + const ProcessInfo& rCurrentProcessInfo) override; + + ///@} + ///@name Access + ///@{ + + + ///@} + ///@name Inquiry + ///@{ + + + ///@} + ///@name Input and output + ///@{ + + std::string Info() const override + { + std::stringstream buffer; + buffer << "NavierStokesP2P1ContinuousWallCondition" << TDim << "D"; + return buffer.str(); + } + + void PrintInfo(std::ostream& rOStream) const override + { + rOStream << "NavierStokesP2P1ContinuousWallCondition"; + } + + void PrintData(std::ostream& rOStream) const override + { + } + + ///@} + ///@name Friends + ///@{ + + + ///@} +protected: + ///@name Protected static Member Variables + ///@{ + + + ///@} + ///@name Protected member Variables + ///@{ + + + ///@} + ///@name Protected Operators + ///@{ + + + ///@} + ///@name Protected Operations + ///@{ + + /** + * @brief Calculates the Gauss point RHS contribution + * This method calculates the current Gauss point RHS contribution and saves it + * in the provided array. Note that the input data container is expected to + * already contain the data at the Gauss point of interest. + * @param rLHS Reference to the RHS output vector + * @param rData Condition data container + * @param rProcessInfo Reference to the ProcessInfo container + */ + void AddGaussPointRHSContribution( + VectorType& rRHS, + const ConditionDataStruct& rData, + const ProcessInfo& rProcessInfo); + + /** + * @brief Calculates the RHS Neumann BC contribution + * This method calculates the Neumann BC pressure flux contribution + * Note that the Neumann BC value is expected to be stored in the historical + * database within the EXTERNAL_PRESSURE variable. + * @param rRHS Reference to the RHS output vector + * @param data Condition data container + */ + void ComputeRHSNeumannContribution( + VectorType& rRHS, + const ConditionDataStruct& data); + + /** + * @brief Calculates and adds the RHS outlet inflow prevention contribution + * This method calculates and adds an extra numerical contribution to the RHS in order + * to prevent uncontrolled system energy growth coming from inflow in free-boundaries. + * More information can be found in Dong et al. 2014 (https://doi.org/10.1016/j.jcp.2013.12.042). + * @param rRHS Reference to RHS vector + * @param rData Condition data container + * @param rProcessInfo Reference to the ProcessInfo container + */ + void ComputeRHSOutletInflowContribution( + VectorType& rRHS, + const ConditionDataStruct& rData, + const ProcessInfo& rProcessInfo); + + ///@} + ///@name Protected Access + ///@{ + + + ///@} + ///@name Protected Inquiry + ///@{ + + + ///@} + ///@name Protected LifeCycle + ///@{ + + + ///@} +private: + ///@name Static Member Variables + ///@{ + + + ///@} + ///@name Member Variables + ///@{ + + + ///@} + ///@name Serialization + ///@{ + + friend class Serializer; + + void save(Serializer& rSerializer) const override + { + KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, Condition); + } + + void load(Serializer& rSerializer) override + { + KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, Condition); + } + + ///@} + ///@name Private Operators + ///@{ + + + ///@} + ///@name Private Operations + ///@{ + + /** + * @brief Calculate the condition unit normal + * This method calculates the current condition unit normal + * @param rUnitNormal Reference to the current condition unit normal + */ + void CalculateUnitNormal(array_1d& rUnitNormal); + + template + int WallModelCheckCall(const ProcessInfo& rProcessInfo) const + { + return TWallModelType::Check(this, rProcessInfo); + } + + template + void AddWallModelRightHandSideCall( + VectorType& rRHS, + const ProcessInfo& rProcessInfo) + { + TWallModelType::AddWallModelRightHandSide(rRHS, this, rProcessInfo); + } + + template + void AddWallModelLeftHandSideCall( + MatrixType& rLHS, + const ProcessInfo& rProcessInfo) + { + TWallModelType::AddWallModelLeftHandSide(rLHS, this, rProcessInfo); + } + + template + void AddWallModelLocalSystemCall( + MatrixType& rLHS, + VectorType& rRHS, + const ProcessInfo& rProcessInfo) + { + TWallModelType::AddWallModelLocalSystem(rLHS, rRHS, this, rProcessInfo); + } + + ///@} + ///@name Private Access + ///@{ + + + ///@} + ///@name Private Inquiry + ///@{ + + + ///@} + ///@name Un accessible methods + ///@{ + + + ///@} +}; // Class NavierStokesP2P1ContinuousWallCondition + +///@} +///@name Type Definitions +///@{ + + +///@} +///@name Input and output +///@{ + + +/// input stream function +template< unsigned int TDim, unsigned int TNumNodes, class TWallModel > +inline std::istream& operator >> (std::istream& rIStream, NavierStokesP2P1ContinuousWallCondition& rThis) +{ + return rIStream; +} + +/// output stream function +template< unsigned int TDim, unsigned int TNumNodes, class TWallModel > +inline std::ostream& operator << (std::ostream& rOStream, const NavierStokesP2P1ContinuousWallCondition& rThis) +{ + rThis.PrintInfo(rOStream); + rOStream << std::endl; + rThis.PrintData(rOStream); + + return rOStream; +} + +///@} + +///@} addtogroup block + + +} // namespace Kratos. diff --git a/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.cpp b/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.cpp new file mode 100644 index 000000000000..47918b31b371 --- /dev/null +++ b/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.cpp @@ -0,0 +1,4002 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + +// System includes + + +// External includes + + +// Project includes +#include "utilities/element_size_calculator.h" + +// Application includes +#include "incompressible_navier_stokes_p2_p1_continuous.h" + +namespace Kratos +{ + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Life cycle + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous(IndexType NewId) + : Element(NewId) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + const NodesArrayType& ThisNodes) + : Element(NewId, ThisNodes) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry) + : Element(NewId, pGeometry) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry, + Properties::Pointer pProperties) + : Element(NewId, pGeometry, pProperties) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::~IncompressibleNavierStokesP2P1Continuous() +{} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public Operations + +template< unsigned int TDim > +Element::Pointer IncompressibleNavierStokesP2P1Continuous::Create( + IndexType NewId, + NodesArrayType const& ThisNodes, + Properties::Pointer pProperties) const +{ + return Kratos::make_intrusive>(NewId, this->GetGeometry().Create(ThisNodes), pProperties); +} + +template< unsigned int TDim > +Element::Pointer IncompressibleNavierStokesP2P1Continuous::Create( + IndexType NewId, + GeometryType::Pointer pGeom, + Properties::Pointer pProperties) const +{ + return Kratos::make_intrusive>(NewId, pGeom, pProperties); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::Initialize(const ProcessInfo& rCurrentProcessInfo) +{ + KRATOS_TRY; + + // If we are restarting, the constitutive law will be already defined + if (mpConstitutiveLaw == nullptr) { + const auto& r_properties = this->GetProperties(); + KRATOS_ERROR_IF_NOT(r_properties.Has(CONSTITUTIVE_LAW)) + << "In initialization of Element " << this->Info() + << ": No CONSTITUTIVE_LAW defined for property " + << r_properties.Id() << "." << std::endl; + + mpConstitutiveLaw = r_properties[CONSTITUTIVE_LAW]->Clone(); + + const auto& r_geometry = this->GetGeometry(); + const auto& r_shape_functions = r_geometry.ShapeFunctionsValues(GeometryData::IntegrationMethod::GI_GAUSS_1); + mpConstitutiveLaw->InitializeMaterial(r_properties, r_geometry, row(r_shape_functions,0)); + } + + KRATOS_CATCH(""); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::EquationIdVector( + EquationIdVectorType &rResult, + const ProcessInfo &rCurrentProcessInfo) const +{ + if (rResult.size() != LocalSize) { + rResult.resize(LocalSize, false); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_X, x_pos).EquationId(); + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Y, x_pos+1).EquationId(); + if constexpr (TDim == 3) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Z, x_pos+2).EquationId(); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(PRESSURE, p_pos).EquationId(); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::GetDofList( + DofsVectorType &rElementalDofList, + const ProcessInfo &rCurrentProcessInfo) const +{ + if (rElementalDofList.size() != LocalSize) { + rElementalDofList.resize(LocalSize); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_X, x_pos); + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Y, x_pos+1); + if constexpr (TDim == 3) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Z, x_pos+2); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(PRESSURE, p_pos); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateLocalSystem( + MatrixType& rLeftHandSideMatrix, + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) +{ + // Resize and intialize output + if (rLeftHandSideMatrix.size1() != LocalSize || rLeftHandSideMatrix.size2() != LocalSize) { + rLeftHandSideMatrix.resize(LocalSize, LocalSize, false); + } + + if (rRightHandSideVector.size() != LocalSize) { + rRightHandSideVector.resize(LocalSize, false); + } + + noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize, LocalSize); + noalias(rRightHandSideVector) = ZeroVector(LocalSize); + + // Initialize element data + ElementDataContainer aux_data; + SetElementData(rCurrentProcessInfo, aux_data); + + // Initialize constitutive law parameters + const auto& r_geom = this->GetGeometry(); + const auto p_prop = this->GetProperties(); + ConstitutiveLaw::Parameters cons_law_params(r_geom, p_prop, rCurrentProcessInfo); + + cons_law_params.SetStrainVector(aux_data.StrainRate); + cons_law_params.SetStressVector(aux_data.ShearStress); + cons_law_params.SetConstitutiveMatrix(aux_data.ConstitutiveMatrix); + + auto& cons_law_options = cons_law_params.GetOptions(); + cons_law_options.Set(ConstitutiveLaw::COMPUTE_STRESS); + cons_law_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); + + // Calculate kinematics + Vector weights; + Matrix velocity_N; + Matrix pressure_N; + GeometryType::ShapeFunctionsGradientsType velocity_DN; + GeometryType::ShapeFunctionsGradientsType pressure_DN; + DenseVector velocity_DDN; + CalculateKinematics(weights, velocity_N, pressure_N, velocity_DN, pressure_DN, velocity_DDN); + + // Loop Gauss points + const SizeType n_gauss = r_geom.IntegrationPointsNumber(IntegrationMethod); + for (IndexType g = 0; g < n_gauss; ++g) { + // Set current Gauss point kinematics + noalias(aux_data.N_v) = row(velocity_N, g); + noalias(aux_data.N_p) = row(pressure_N, g); + noalias(aux_data.DN_v) = velocity_DN[g]; + noalias(aux_data.DN_p) = pressure_DN[g]; + aux_data.DDN_v = velocity_DDN[g]; + aux_data.Weight = weights[g]; + + // Calculate current Gauss point material response + CalculateStrainRate(aux_data); + mpConstitutiveLaw->CalculateMaterialResponseCauchy(cons_law_params); + mpConstitutiveLaw->CalculateValue(cons_law_params, EFFECTIVE_VISCOSITY, aux_data.EffectiveViscosity); + + // Assemble standard Galerkin contribution + AddGaussPointLeftHandSideContribution(aux_data, rLeftHandSideMatrix); + AddGaussPointRightHandSideContribution(aux_data, rRightHandSideVector); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public Inquiry + +template< unsigned int TDim > +int IncompressibleNavierStokesP2P1Continuous::Check(const ProcessInfo &rCurrentProcessInfo) const +{ + KRATOS_TRY; + int out = Element::Check(rCurrentProcessInfo); + KRATOS_ERROR_IF_NOT(out == 0) + << "Error in base class Check for Element " << this->Info() << std::endl + << "Error code is " << out << std::endl; + + return 0; + + KRATOS_CATCH(""); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public I/O + +template< unsigned int TDim > +const Parameters IncompressibleNavierStokesP2P1Continuous::GetSpecifications() const +{ + const Parameters specifications = Parameters(R"({ + "time_integration" : ["implicit"], + "framework" : "ale", + "symmetric_lhs" : false, + "positive_definite_lhs" : true, + "output" : { + "gauss_point" : [""], + "nodal_historical" : ["VELOCITY","PRESSURE"], + "nodal_non_historical" : [], + "entity" : [] + }, + "required_variables" : ["VELOCITY","ACCELERATION","MESH_VELOCITY","PRESSURE","IS_STRUCTURE","DISPLACEMENT","BODY_FORCE","NODAL_AREA","NODAL_H","ADVPROJ","DIVPROJ","REACTION","REACTION_WATER_PRESSURE","EXTERNAL_PRESSURE","NORMAL","Y_WALL","Q_VALUE"] + "required_dofs" : [], + "flags_used" : [], + "compatible_geometries" : ["Triangle2D6","Tetrahedra3D10"], + "element_integrates_in_time" : true, + "compatible_constitutive_laws": { + "type" : ["Newtonian2DLaw","Newtonian3DLaw","NewtonianTemperatureDependent2DLaw","NewtonianTemperatureDependent3DLaw","Euler2DLaw","Euler3DLaw"], + "dimension" : ["2D","3D"], + "strain_size" : [3,6] + }, + "required_polynomial_degree_of_geometry" : 2, + "documentation" : + "This implements a div-stable incompressible Navier-Stokes element with bubble function enrichment. No viscous behavior is hardcoded, meaning that any fluid constitutive model can be used through a constitutive law." + })"); + + if (TDim == 2) { + std::vector dofs_2d({"VELOCITY_X","VELOCITY_Y","PRESSURE"}); + specifications["required_dofs"].SetStringArray(dofs_2d); + } else { + std::vector dofs_3d({"VELOCITY_X","VELOCITY_Y","VELOCITY_Z","PRESSURE"}); + specifications["required_dofs"].SetStringArray(dofs_3d); + } + + return specifications; +} + +template< unsigned int TDim > +std::string IncompressibleNavierStokesP2P1Continuous::Info() const +{ + std::stringstream buffer; + buffer << "IncompressibleNavierStokesP2P1Continuous" << TDim << "D" << VelocityNumNodes << "N #" << this->Id(); + return buffer.str(); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::PrintInfo(std::ostream& rOStream) const +{ + rOStream << this->Info() << std::endl; + + if (mpConstitutiveLaw != nullptr) { + rOStream << "with constitutive law " << std::endl; + mpConstitutiveLaw->PrintInfo(rOStream); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Private operations + +template +void IncompressibleNavierStokesP2P1Continuous::SetElementData( + const ProcessInfo& rProcessInfo, + ElementDataContainer &rData) +{ + // Set nodal data + const auto& r_geom = this->GetGeometry(); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + const auto& r_v = r_geom[i].FastGetSolutionStepValue(VELOCITY); + const auto& r_v_n = r_geom[i].FastGetSolutionStepValue(VELOCITY, 1); + const auto& r_v_nn = r_geom[i].FastGetSolutionStepValue(VELOCITY, 2); + const auto& r_v_mesh = r_geom[i].FastGetSolutionStepValue(MESH_VELOCITY); + const auto& r_body_force = r_geom[i].FastGetSolutionStepValue(BODY_FORCE); + + for (IndexType d = 0; d < TDim; ++d) { + rData.Velocity(i, d) = r_v[d]; + rData.VelocityOld1(i, d) = r_v_n[d]; + rData.VelocityOld2(i, d) = r_v_nn[d]; + rData.MeshVelocity(i, d) = r_v_mesh[d]; + rData.BodyForce(i, d) = r_body_force[d]; + } + } + + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rData.Pressure[i] = r_geom[i].FastGetSolutionStepValue(PRESSURE); + } + + // Set material values + rData.Density = this->GetProperties().GetValue(DENSITY); + + // Set stabilization values + rData.StabC1 = 12.0; + rData.StabC2 = 2.0; + rData.DynamicTau = rProcessInfo[DYNAMIC_TAU]; + rData.ElementSize = ElementSizeCalculator::AverageElementSize(r_geom); + + // Set ProcessInfo data + rData.DeltaTime = rProcessInfo[DELTA_TIME]; + const auto& r_bdf_coefs = rProcessInfo[BDF_COEFFICIENTS]; + rData.BDF0 = r_bdf_coefs[0]; + rData.BDF1 = r_bdf_coefs[1]; + rData.BDF2 = r_bdf_coefs[2]; +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateKinematics( + Vector& rGaussWeights, + Matrix& rVelocityN, + Matrix& rPressureN, + GeometryType::ShapeFunctionsGradientsType& rVelocityDNDX, + GeometryType::ShapeFunctionsGradientsType& rPressureDNDX, + DenseVector& rVelocityDDNDDX) +{ + // Get element geometry + const auto& r_geom = this->GetGeometry(); + + // Integration rule data + // Note that we use the same for both velocity and pressure interpolations + const SizeType n_gauss = r_geom.IntegrationPointsNumber(IntegrationMethod); + const auto integration_points = r_geom.IntegrationPoints(IntegrationMethod); + + // Calculate Jacobians at integration points + Matrix J; + Matrix inv_J; + double det_J; + Vector det_J_vect(n_gauss); + std::vector> inv_J_vect(n_gauss); + for (IndexType g = 0; g < n_gauss; ++g) { + r_geom.Jacobian(J, g, IntegrationMethod); + MathUtils::InvertMatrix(J, inv_J, det_J); + det_J_vect[g] = det_J; + noalias(inv_J_vect[g]) = inv_J; + } + + // Calculate velocity kinematics from the geometry (P2 interpolation) + rVelocityN = r_geom.ShapeFunctionsValues(IntegrationMethod); + const auto& r_DN_De_v = r_geom.ShapeFunctionsLocalGradients(IntegrationMethod); + if (rVelocityDNDX.size() != n_gauss) { + rVelocityDNDX.resize(n_gauss, false); + } + for (IndexType g = 0; g < n_gauss; ++g) { + rVelocityDNDX[g] = prod(r_DN_De_v[g], inv_J_vect[g]); + } + GeometryUtils::ShapeFunctionsSecondDerivativesTransformOnAllIntegrationPoints(rVelocityDDNDDX, r_geom, IntegrationMethod); + + // Calculate pressure kinematics from an auxiliary geometry (P1 interpolation) + GeometryType::UniquePointer p_aux_geom = nullptr; + if constexpr (TDim == 2) { + p_aux_geom = Kratos::make_unique>(r_geom(0), r_geom(1), r_geom(2)); + } else { + p_aux_geom = Kratos::make_unique>(r_geom(0), r_geom(1), r_geom(2), r_geom(3)); + } + rPressureN = p_aux_geom->ShapeFunctionsValues(IntegrationMethod); + if (rPressureDNDX.size() != n_gauss) { + rPressureDNDX.resize(n_gauss, false); + } + const auto& r_DN_De_p = p_aux_geom->ShapeFunctionsLocalGradients(IntegrationMethod); + for (IndexType g = 0; g < n_gauss; ++g) { + rPressureDNDX[g] = prod(r_DN_De_p[g], inv_J_vect[g]); + } + + // Calculate integration points weight + if (rGaussWeights.size() != n_gauss) { + rGaussWeights.resize(n_gauss, false); + } + for (IndexType g = 0; g < n_gauss; ++g) { + rGaussWeights[g] = det_J_vect[g] * integration_points[g].Weight(); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateStrainRate(ElementDataContainer& rData) +{ + if (rData.StrainRate.size() != StrainSize) { + rData.StrainRate.resize(StrainSize, false); + } + noalias(rData.StrainRate) = ZeroVector(StrainSize); + + if constexpr (TDim == 2) { + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rData.StrainRate[0] += rData.DN_v(i,0)*rData.Velocity(i,0); + rData.StrainRate[1] += rData.DN_v(i,1)*rData.Velocity(i,1); + rData.StrainRate[2] += rData.DN_v(i,0)*rData.Velocity(i,1) + rData.DN_v(i,1)*rData.Velocity(i,0); + } + } else { + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rData.StrainRate[0] += rData.DN_v(i,0)*rData.Velocity(i,0); + rData.StrainRate[1] += rData.DN_v(i,1)*rData.Velocity(i,1); + rData.StrainRate[2] += rData.DN_v(i,2)*rData.Velocity(i,2); + rData.StrainRate[3] += rData.DN_v(i,0)*rData.Velocity(i,1) + rData.DN_v(i,1)*rData.Velocity(i,0); + rData.StrainRate[4] += rData.DN_v(i,1)*rData.Velocity(i,2) + rData.DN_v(i,2)*rData.Velocity(i,1); + rData.StrainRate[5] += rData.DN_v(i,0)*rData.Velocity(i,2) + rData.DN_v(i,2)*rData.Velocity(i,0); + } + } + +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<2>::AddGaussPointLeftHandSideContribution( + const ElementDataContainer& rData, + MatrixType& rLHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Calculate convective velocity + const BoundedMatrix vconv = rData.Velocity - rData.MeshVelocity; + + // Get constitutive matrix + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble LHS contribution + const double gauss_weight = rData.Weight; + const double crLHS0 = C(0,0)*DN_v(0,0) + C(0,2)*DN_v(0,1); + const double crLHS1 = C(0,2)*DN_v(0,0); + const double crLHS2 = C(2,2)*DN_v(0,1) + crLHS1; + const double crLHS3 = N_v[0]*vconv(0,0) + N_v[1]*vconv(1,0) + N_v[2]*vconv(2,0) + N_v[3]*vconv(3,0) + N_v[4]*vconv(4,0) + N_v[5]*vconv(5,0); + const double crLHS4 = N_v[0]*vconv(0,1) + N_v[1]*vconv(1,1) + N_v[2]*vconv(2,1) + N_v[3]*vconv(3,1) + N_v[4]*vconv(4,1) + N_v[5]*vconv(5,1); + const double crLHS5 = rho*stab_c2*std::sqrt(std::pow(crLHS3, 2) + std::pow(crLHS4, 2)); + const double crLHS6 = crLHS5*h/stab_c1 + mu; + const double crLHS7 = 1.0*C(0,0); + const double crLHS8 = C(0,2)*DDN_v[0](0,0); + const double crLHS9 = 1.0*DDN_v[0](0,1); + const double crLHS10 = rho*(DN_v(0,0)*crLHS3 + DN_v(0,1)*crLHS4); + const double crLHS11 = rData.BDF0*rho; + const double crLHS12 = N_v[0]*crLHS11; + const double crLHS13 = -crLHS10 - crLHS12; + const double crLHS14 = C(0,2)*crLHS9 + C(2,2)*crLHS9 + DDN_v[0](0,0)*crLHS7 + crLHS13 + 1.0*crLHS8; + const double crLHS15 = 1.0/(crLHS5/h + dyn_tau*rho/rData.DeltaTime + mu*stab_c1/std::pow(h, 2)); + const double crLHS16 = crLHS10*crLHS15; + const double crLHS17 = rho*(DN_v(0,0)*vconv(0,0) + DN_v(0,1)*vconv(0,1) + DN_v(1,0)*vconv(1,0) + DN_v(1,1)*vconv(1,1) + DN_v(2,0)*vconv(2,0) + DN_v(2,1)*vconv(2,1) + DN_v(3,0)*vconv(3,0) + DN_v(3,1)*vconv(3,1) + DN_v(4,0)*vconv(4,0) + DN_v(4,1)*vconv(4,1) + DN_v(5,0)*vconv(5,0) + DN_v(5,1)*vconv(5,1)); + const double crLHS18 = N_v[0]*crLHS17; + const double crLHS19 = crLHS15*crLHS18; + const double crLHS20 = std::pow(N_v[0], 2)*crLHS11 + N_v[0]*crLHS10; + const double crLHS21 = C(0,1)*DN_v(0,1) + crLHS1; + const double crLHS22 = C(1,2)*DN_v(0,1); + const double crLHS23 = C(2,2)*DN_v(0,0) + crLHS22; + const double crLHS24 = DN_v(0,0)*crLHS6; + const double crLHS25 = DN_v(0,1)*crLHS24; + const double crLHS26 = C(0,1)*DDN_v[0](0,1) + C(1,2)*DDN_v[0](0,1) + C(2,2)*DDN_v[0](0,0) + crLHS8; + const double crLHS27 = C(0,0)*DN_v(1,0) + C(0,2)*DN_v(1,1); + const double crLHS28 = C(0,2)*DN_v(1,0); + const double crLHS29 = C(2,2)*DN_v(1,1) + crLHS28; + const double crLHS30 = DN_v(1,0)*crLHS24; + const double crLHS31 = C(0,2)*DDN_v[1](0,0); + const double crLHS32 = 1.0*DDN_v[1](0,1); + const double crLHS33 = rho*(DN_v(1,0)*crLHS3 + DN_v(1,1)*crLHS4); + const double crLHS34 = N_v[1]*crLHS11; + const double crLHS35 = -crLHS33 - crLHS34; + const double crLHS36 = C(0,2)*crLHS32 + C(2,2)*crLHS32 + DDN_v[1](0,0)*crLHS7 + 1.0*crLHS31 + crLHS35; + const double crLHS37 = N_v[1]*crLHS12; + const double crLHS38 = N_v[0]*crLHS33 + crLHS37; + const double crLHS39 = C(0,1)*DN_v(1,1) + crLHS28; + const double crLHS40 = C(1,2)*DN_v(1,1); + const double crLHS41 = C(2,2)*DN_v(1,0) + crLHS40; + const double crLHS42 = DN_v(1,1)*crLHS24; + const double crLHS43 = C(0,1)*DDN_v[1](0,1) + C(1,2)*DDN_v[1](0,1) + C(2,2)*DDN_v[1](0,0) + crLHS31; + const double crLHS44 = C(0,0)*DN_v(2,0) + C(0,2)*DN_v(2,1); + const double crLHS45 = C(0,2)*DN_v(2,0); + const double crLHS46 = C(2,2)*DN_v(2,1) + crLHS45; + const double crLHS47 = DN_v(2,0)*crLHS24; + const double crLHS48 = C(0,2)*DDN_v[2](0,0); + const double crLHS49 = 1.0*DDN_v[2](0,1); + const double crLHS50 = rho*(DN_v(2,0)*crLHS3 + DN_v(2,1)*crLHS4); + const double crLHS51 = N_v[2]*crLHS11; + const double crLHS52 = -crLHS50 - crLHS51; + const double crLHS53 = C(0,2)*crLHS49 + C(2,2)*crLHS49 + DDN_v[2](0,0)*crLHS7 + 1.0*crLHS48 + crLHS52; + const double crLHS54 = N_v[2]*crLHS12; + const double crLHS55 = N_v[0]*crLHS50 + crLHS54; + const double crLHS56 = C(0,1)*DN_v(2,1) + crLHS45; + const double crLHS57 = C(1,2)*DN_v(2,1); + const double crLHS58 = C(2,2)*DN_v(2,0) + crLHS57; + const double crLHS59 = DN_v(2,1)*crLHS24; + const double crLHS60 = C(0,1)*DDN_v[2](0,1) + C(1,2)*DDN_v[2](0,1) + C(2,2)*DDN_v[2](0,0) + crLHS48; + const double crLHS61 = C(0,0)*DN_v(3,0) + C(0,2)*DN_v(3,1); + const double crLHS62 = C(0,2)*DN_v(3,0); + const double crLHS63 = C(2,2)*DN_v(3,1) + crLHS62; + const double crLHS64 = DN_v(3,0)*crLHS24; + const double crLHS65 = C(0,2)*DDN_v[3](0,0); + const double crLHS66 = 1.0*DDN_v[3](0,1); + const double crLHS67 = rho*(DN_v(3,0)*crLHS3 + DN_v(3,1)*crLHS4); + const double crLHS68 = N_v[3]*crLHS11; + const double crLHS69 = -crLHS67 - crLHS68; + const double crLHS70 = C(0,2)*crLHS66 + C(2,2)*crLHS66 + DDN_v[3](0,0)*crLHS7 + 1.0*crLHS65 + crLHS69; + const double crLHS71 = N_v[3]*crLHS12; + const double crLHS72 = N_v[0]*crLHS67 + crLHS71; + const double crLHS73 = C(0,1)*DN_v(3,1) + crLHS62; + const double crLHS74 = C(1,2)*DN_v(3,1); + const double crLHS75 = C(2,2)*DN_v(3,0) + crLHS74; + const double crLHS76 = DN_v(3,1)*crLHS24; + const double crLHS77 = C(0,1)*DDN_v[3](0,1) + C(1,2)*DDN_v[3](0,1) + C(2,2)*DDN_v[3](0,0) + crLHS65; + const double crLHS78 = C(0,0)*DN_v(4,0) + C(0,2)*DN_v(4,1); + const double crLHS79 = C(0,2)*DN_v(4,0); + const double crLHS80 = C(2,2)*DN_v(4,1) + crLHS79; + const double crLHS81 = DN_v(4,0)*crLHS24; + const double crLHS82 = C(0,2)*DDN_v[4](0,0); + const double crLHS83 = 1.0*DDN_v[4](0,1); + const double crLHS84 = rho*(DN_v(4,0)*crLHS3 + DN_v(4,1)*crLHS4); + const double crLHS85 = N_v[4]*crLHS11; + const double crLHS86 = -crLHS84 - crLHS85; + const double crLHS87 = C(0,2)*crLHS83 + C(2,2)*crLHS83 + DDN_v[4](0,0)*crLHS7 + 1.0*crLHS82 + crLHS86; + const double crLHS88 = N_v[4]*crLHS12; + const double crLHS89 = N_v[0]*crLHS84 + crLHS88; + const double crLHS90 = C(0,1)*DN_v(4,1) + crLHS79; + const double crLHS91 = C(1,2)*DN_v(4,1); + const double crLHS92 = C(2,2)*DN_v(4,0) + crLHS91; + const double crLHS93 = DN_v(4,1)*crLHS24; + const double crLHS94 = C(0,1)*DDN_v[4](0,1) + C(1,2)*DDN_v[4](0,1) + C(2,2)*DDN_v[4](0,0) + crLHS82; + const double crLHS95 = C(0,0)*DN_v(5,0) + C(0,2)*DN_v(5,1); + const double crLHS96 = C(0,2)*DN_v(5,0); + const double crLHS97 = C(2,2)*DN_v(5,1) + crLHS96; + const double crLHS98 = DN_v(5,0)*crLHS24; + const double crLHS99 = C(0,2)*DDN_v[5](0,0); + const double crLHS100 = 1.0*DDN_v[5](0,1); + const double crLHS101 = rho*(DN_v(5,0)*crLHS3 + DN_v(5,1)*crLHS4); + const double crLHS102 = -N_v[5]*crLHS11 - crLHS101; + const double crLHS103 = C(0,2)*crLHS100 + C(2,2)*crLHS100 + DDN_v[5](0,0)*crLHS7 + crLHS102 + 1.0*crLHS99; + const double crLHS104 = N_v[5]*crLHS12; + const double crLHS105 = N_v[0]*crLHS101 + crLHS104; + const double crLHS106 = C(0,1)*DN_v(5,1) + crLHS96; + const double crLHS107 = C(1,2)*DN_v(5,1); + const double crLHS108 = C(2,2)*DN_v(5,0) + crLHS107; + const double crLHS109 = DN_v(5,1)*crLHS24; + const double crLHS110 = C(0,1)*DDN_v[5](0,1) + C(1,2)*DDN_v[5](0,1) + C(2,2)*DDN_v[5](0,0) + crLHS99; + const double crLHS111 = -DN_v(0,0)*N_p[0]; + const double crLHS112 = DN_p(0,0)*crLHS15; + const double crLHS113 = -DN_v(0,0)*N_p[1]; + const double crLHS114 = DN_p(1,0)*crLHS15; + const double crLHS115 = -DN_v(0,0)*N_p[2]; + const double crLHS116 = DN_p(2,0)*crLHS15; + const double crLHS117 = C(0,1)*DN_v(0,0) + crLHS22; + const double crLHS118 = C(1,2)*DDN_v[0](1,1); + const double crLHS119 = C(0,1)*DDN_v[0](1,0) + C(0,2)*DDN_v[0](1,0) + C(2,2)*DDN_v[0](1,1) + crLHS118; + const double crLHS120 = C(1,1)*DN_v(0,1) + C(1,2)*DN_v(0,0); + const double crLHS121 = 1.0*C(1,1); + const double crLHS122 = 1.0*DDN_v[0](1,0); + const double crLHS123 = C(1,2)*crLHS122 + C(2,2)*crLHS122 + DDN_v[0](1,1)*crLHS121 + 1.0*crLHS118 + crLHS13; + const double crLHS124 = C(0,1)*DN_v(1,0) + crLHS40; + const double crLHS125 = DN_v(0,1)*crLHS6; + const double crLHS126 = DN_v(1,0)*crLHS125; + const double crLHS127 = C(1,2)*DDN_v[1](1,1); + const double crLHS128 = C(0,1)*DDN_v[1](1,0) + C(0,2)*DDN_v[1](1,0) + C(2,2)*DDN_v[1](1,1) + crLHS127; + const double crLHS129 = C(1,1)*DN_v(1,1) + C(1,2)*DN_v(1,0); + const double crLHS130 = DN_v(1,1)*crLHS125; + const double crLHS131 = 1.0*DDN_v[1](1,0); + const double crLHS132 = C(1,2)*crLHS131 + C(2,2)*crLHS131 + DDN_v[1](1,1)*crLHS121 + 1.0*crLHS127 + crLHS35; + const double crLHS133 = C(0,1)*DN_v(2,0) + crLHS57; + const double crLHS134 = DN_v(2,0)*crLHS125; + const double crLHS135 = C(1,2)*DDN_v[2](1,1); + const double crLHS136 = C(0,1)*DDN_v[2](1,0) + C(0,2)*DDN_v[2](1,0) + C(2,2)*DDN_v[2](1,1) + crLHS135; + const double crLHS137 = C(1,1)*DN_v(2,1) + C(1,2)*DN_v(2,0); + const double crLHS138 = DN_v(2,1)*crLHS125; + const double crLHS139 = 1.0*DDN_v[2](1,0); + const double crLHS140 = C(1,2)*crLHS139 + C(2,2)*crLHS139 + DDN_v[2](1,1)*crLHS121 + 1.0*crLHS135 + crLHS52; + const double crLHS141 = C(0,1)*DN_v(3,0) + crLHS74; + const double crLHS142 = DN_v(3,0)*crLHS125; + const double crLHS143 = C(1,2)*DDN_v[3](1,1); + const double crLHS144 = C(0,1)*DDN_v[3](1,0) + C(0,2)*DDN_v[3](1,0) + C(2,2)*DDN_v[3](1,1) + crLHS143; + const double crLHS145 = C(1,1)*DN_v(3,1) + C(1,2)*DN_v(3,0); + const double crLHS146 = DN_v(3,1)*crLHS125; + const double crLHS147 = 1.0*DDN_v[3](1,0); + const double crLHS148 = C(1,2)*crLHS147 + C(2,2)*crLHS147 + DDN_v[3](1,1)*crLHS121 + 1.0*crLHS143 + crLHS69; + const double crLHS149 = C(0,1)*DN_v(4,0) + crLHS91; + const double crLHS150 = DN_v(4,0)*crLHS125; + const double crLHS151 = C(1,2)*DDN_v[4](1,1); + const double crLHS152 = C(0,1)*DDN_v[4](1,0) + C(0,2)*DDN_v[4](1,0) + C(2,2)*DDN_v[4](1,1) + crLHS151; + const double crLHS153 = C(1,1)*DN_v(4,1) + C(1,2)*DN_v(4,0); + const double crLHS154 = DN_v(4,1)*crLHS125; + const double crLHS155 = 1.0*DDN_v[4](1,0); + const double crLHS156 = C(1,2)*crLHS155 + C(2,2)*crLHS155 + DDN_v[4](1,1)*crLHS121 + 1.0*crLHS151 + crLHS86; + const double crLHS157 = C(0,1)*DN_v(5,0) + crLHS107; + const double crLHS158 = DN_v(5,0)*crLHS125; + const double crLHS159 = C(1,2)*DDN_v[5](1,1); + const double crLHS160 = C(0,1)*DDN_v[5](1,0) + C(0,2)*DDN_v[5](1,0) + C(2,2)*DDN_v[5](1,1) + crLHS159; + const double crLHS161 = C(1,1)*DN_v(5,1) + C(1,2)*DN_v(5,0); + const double crLHS162 = DN_v(5,1)*crLHS125; + const double crLHS163 = 1.0*DDN_v[5](1,0); + const double crLHS164 = C(1,2)*crLHS163 + C(2,2)*crLHS163 + DDN_v[5](1,1)*crLHS121 + crLHS102 + 1.0*crLHS159; + const double crLHS165 = -DN_v(0,1)*N_p[0]; + const double crLHS166 = DN_p(0,1)*crLHS15; + const double crLHS167 = -DN_v(0,1)*N_p[1]; + const double crLHS168 = DN_p(1,1)*crLHS15; + const double crLHS169 = -DN_v(0,1)*N_p[2]; + const double crLHS170 = DN_p(2,1)*crLHS15; + const double crLHS171 = crLHS15*crLHS33; + const double crLHS172 = N_v[1]*crLHS17; + const double crLHS173 = crLHS15*crLHS172; + const double crLHS174 = N_v[1]*crLHS10 + crLHS37; + const double crLHS175 = std::pow(N_v[1], 2)*crLHS11 + N_v[1]*crLHS33; + const double crLHS176 = DN_v(1,0)*crLHS6; + const double crLHS177 = DN_v(1,1)*crLHS176; + const double crLHS178 = DN_v(2,0)*crLHS176; + const double crLHS179 = N_v[2]*crLHS34; + const double crLHS180 = N_v[1]*crLHS50 + crLHS179; + const double crLHS181 = DN_v(2,1)*crLHS176; + const double crLHS182 = DN_v(3,0)*crLHS176; + const double crLHS183 = N_v[3]*crLHS34; + const double crLHS184 = N_v[1]*crLHS67 + crLHS183; + const double crLHS185 = DN_v(3,1)*crLHS176; + const double crLHS186 = DN_v(4,0)*crLHS176; + const double crLHS187 = N_v[4]*crLHS34; + const double crLHS188 = N_v[1]*crLHS84 + crLHS187; + const double crLHS189 = DN_v(4,1)*crLHS176; + const double crLHS190 = DN_v(5,0)*crLHS176; + const double crLHS191 = N_v[5]*crLHS34; + const double crLHS192 = N_v[1]*crLHS101 + crLHS191; + const double crLHS193 = DN_v(5,1)*crLHS176; + const double crLHS194 = -DN_v(1,0)*N_p[0]; + const double crLHS195 = -DN_v(1,0)*N_p[1]; + const double crLHS196 = -DN_v(1,0)*N_p[2]; + const double crLHS197 = DN_v(1,1)*crLHS6; + const double crLHS198 = DN_v(2,0)*crLHS197; + const double crLHS199 = DN_v(2,1)*crLHS197; + const double crLHS200 = DN_v(3,0)*crLHS197; + const double crLHS201 = DN_v(3,1)*crLHS197; + const double crLHS202 = DN_v(4,0)*crLHS197; + const double crLHS203 = DN_v(4,1)*crLHS197; + const double crLHS204 = DN_v(5,0)*crLHS197; + const double crLHS205 = DN_v(5,1)*crLHS197; + const double crLHS206 = -DN_v(1,1)*N_p[0]; + const double crLHS207 = -DN_v(1,1)*N_p[1]; + const double crLHS208 = -DN_v(1,1)*N_p[2]; + const double crLHS209 = crLHS15*crLHS50; + const double crLHS210 = N_v[2]*crLHS17; + const double crLHS211 = crLHS15*crLHS210; + const double crLHS212 = N_v[2]*crLHS10 + crLHS54; + const double crLHS213 = N_v[2]*crLHS33 + crLHS179; + const double crLHS214 = std::pow(N_v[2], 2)*crLHS11 + N_v[2]*crLHS50; + const double crLHS215 = DN_v(2,0)*crLHS6; + const double crLHS216 = DN_v(2,1)*crLHS215; + const double crLHS217 = DN_v(3,0)*crLHS215; + const double crLHS218 = N_v[3]*crLHS51; + const double crLHS219 = N_v[2]*crLHS67 + crLHS218; + const double crLHS220 = DN_v(3,1)*crLHS215; + const double crLHS221 = DN_v(4,0)*crLHS215; + const double crLHS222 = N_v[4]*crLHS51; + const double crLHS223 = N_v[2]*crLHS84 + crLHS222; + const double crLHS224 = DN_v(4,1)*crLHS215; + const double crLHS225 = DN_v(5,0)*crLHS215; + const double crLHS226 = N_v[5]*crLHS51; + const double crLHS227 = N_v[2]*crLHS101 + crLHS226; + const double crLHS228 = DN_v(5,1)*crLHS215; + const double crLHS229 = -DN_v(2,0)*N_p[0]; + const double crLHS230 = -DN_v(2,0)*N_p[1]; + const double crLHS231 = -DN_v(2,0)*N_p[2]; + const double crLHS232 = DN_v(2,1)*crLHS6; + const double crLHS233 = DN_v(3,0)*crLHS232; + const double crLHS234 = DN_v(3,1)*crLHS232; + const double crLHS235 = DN_v(4,0)*crLHS232; + const double crLHS236 = DN_v(4,1)*crLHS232; + const double crLHS237 = DN_v(5,0)*crLHS232; + const double crLHS238 = DN_v(5,1)*crLHS232; + const double crLHS239 = -DN_v(2,1)*N_p[0]; + const double crLHS240 = -DN_v(2,1)*N_p[1]; + const double crLHS241 = -DN_v(2,1)*N_p[2]; + const double crLHS242 = crLHS15*crLHS67; + const double crLHS243 = N_v[3]*crLHS17; + const double crLHS244 = crLHS15*crLHS243; + const double crLHS245 = N_v[3]*crLHS10 + crLHS71; + const double crLHS246 = N_v[3]*crLHS33 + crLHS183; + const double crLHS247 = N_v[3]*crLHS50 + crLHS218; + const double crLHS248 = std::pow(N_v[3], 2)*crLHS11 + N_v[3]*crLHS67; + const double crLHS249 = DN_v(3,0)*crLHS6; + const double crLHS250 = DN_v(3,1)*crLHS249; + const double crLHS251 = DN_v(4,0)*crLHS249; + const double crLHS252 = N_v[4]*crLHS68; + const double crLHS253 = N_v[3]*crLHS84 + crLHS252; + const double crLHS254 = DN_v(4,1)*crLHS249; + const double crLHS255 = DN_v(5,0)*crLHS249; + const double crLHS256 = N_v[5]*crLHS68; + const double crLHS257 = N_v[3]*crLHS101 + crLHS256; + const double crLHS258 = DN_v(5,1)*crLHS249; + const double crLHS259 = -DN_v(3,0)*N_p[0]; + const double crLHS260 = -DN_v(3,0)*N_p[1]; + const double crLHS261 = -DN_v(3,0)*N_p[2]; + const double crLHS262 = DN_v(3,1)*crLHS6; + const double crLHS263 = DN_v(4,0)*crLHS262; + const double crLHS264 = DN_v(4,1)*crLHS262; + const double crLHS265 = DN_v(5,0)*crLHS262; + const double crLHS266 = DN_v(5,1)*crLHS262; + const double crLHS267 = -DN_v(3,1)*N_p[0]; + const double crLHS268 = -DN_v(3,1)*N_p[1]; + const double crLHS269 = -DN_v(3,1)*N_p[2]; + const double crLHS270 = crLHS15*crLHS84; + const double crLHS271 = N_v[4]*crLHS17; + const double crLHS272 = crLHS15*crLHS271; + const double crLHS273 = N_v[4]*crLHS10 + crLHS88; + const double crLHS274 = N_v[4]*crLHS33 + crLHS187; + const double crLHS275 = N_v[4]*crLHS50 + crLHS222; + const double crLHS276 = N_v[4]*crLHS67 + crLHS252; + const double crLHS277 = std::pow(N_v[4], 2)*crLHS11 + N_v[4]*crLHS84; + const double crLHS278 = DN_v(4,0)*crLHS6; + const double crLHS279 = DN_v(4,1)*crLHS278; + const double crLHS280 = DN_v(5,0)*crLHS278; + const double crLHS281 = N_v[5]*crLHS85; + const double crLHS282 = N_v[4]*crLHS101 + crLHS281; + const double crLHS283 = DN_v(5,1)*crLHS278; + const double crLHS284 = -DN_v(4,0)*N_p[0]; + const double crLHS285 = -DN_v(4,0)*N_p[1]; + const double crLHS286 = -DN_v(4,0)*N_p[2]; + const double crLHS287 = DN_v(4,1)*crLHS6; + const double crLHS288 = DN_v(5,0)*crLHS287; + const double crLHS289 = DN_v(5,1)*crLHS287; + const double crLHS290 = -DN_v(4,1)*N_p[0]; + const double crLHS291 = -DN_v(4,1)*N_p[1]; + const double crLHS292 = -DN_v(4,1)*N_p[2]; + const double crLHS293 = crLHS101*crLHS15; + const double crLHS294 = N_v[5]*crLHS17; + const double crLHS295 = crLHS15*crLHS294; + const double crLHS296 = N_v[5]*crLHS10 + crLHS104; + const double crLHS297 = N_v[5]*crLHS33 + crLHS191; + const double crLHS298 = N_v[5]*crLHS50 + crLHS226; + const double crLHS299 = N_v[5]*crLHS67 + crLHS256; + const double crLHS300 = N_v[5]*crLHS84 + crLHS281; + const double crLHS301 = std::pow(N_v[5], 2)*crLHS11 + N_v[5]*crLHS101; + const double crLHS302 = DN_v(5,0)*DN_v(5,1)*crLHS6; + const double crLHS303 = -DN_v(5,0)*N_p[0]; + const double crLHS304 = -DN_v(5,0)*N_p[1]; + const double crLHS305 = -DN_v(5,0)*N_p[2]; + const double crLHS306 = -DN_v(5,1)*N_p[0]; + const double crLHS307 = -DN_v(5,1)*N_p[1]; + const double crLHS308 = -DN_v(5,1)*N_p[2]; + const double crLHS309 = crLHS15*gauss_weight; + const double crLHS310 = crLHS309*(DN_p(0,0)*DN_p(1,0) + DN_p(0,1)*DN_p(1,1)); + const double crLHS311 = crLHS309*(DN_p(0,0)*DN_p(2,0) + DN_p(0,1)*DN_p(2,1)); + const double crLHS312 = crLHS309*(DN_p(1,0)*DN_p(2,0) + DN_p(1,1)*DN_p(2,1)); + rLHS(0,0)+=gauss_weight*(std::pow(DN_v(0,0), 2)*crLHS6 + DN_v(0,0)*crLHS0 + DN_v(0,1)*crLHS2 - crLHS14*crLHS16 - crLHS14*crLHS19 + crLHS20); + rLHS(0,1)+=gauss_weight*(DN_v(0,0)*crLHS21 + DN_v(0,1)*crLHS23 - crLHS16*crLHS26 - crLHS19*crLHS26 + crLHS25); + rLHS(0,2)+=gauss_weight*(DN_v(0,0)*crLHS27 + DN_v(0,1)*crLHS29 - crLHS16*crLHS36 - crLHS19*crLHS36 + crLHS30 + crLHS38); + rLHS(0,3)+=gauss_weight*(DN_v(0,0)*crLHS39 + DN_v(0,1)*crLHS41 - crLHS16*crLHS43 - crLHS19*crLHS43 + crLHS42); + rLHS(0,4)+=gauss_weight*(DN_v(0,0)*crLHS44 + DN_v(0,1)*crLHS46 - crLHS16*crLHS53 - crLHS19*crLHS53 + crLHS47 + crLHS55); + rLHS(0,5)+=gauss_weight*(DN_v(0,0)*crLHS56 + DN_v(0,1)*crLHS58 - crLHS16*crLHS60 - crLHS19*crLHS60 + crLHS59); + rLHS(0,6)+=gauss_weight*(DN_v(0,0)*crLHS61 + DN_v(0,1)*crLHS63 - crLHS16*crLHS70 - crLHS19*crLHS70 + crLHS64 + crLHS72); + rLHS(0,7)+=gauss_weight*(DN_v(0,0)*crLHS73 + DN_v(0,1)*crLHS75 - crLHS16*crLHS77 - crLHS19*crLHS77 + crLHS76); + rLHS(0,8)+=gauss_weight*(DN_v(0,0)*crLHS78 + DN_v(0,1)*crLHS80 - crLHS16*crLHS87 - crLHS19*crLHS87 + crLHS81 + crLHS89); + rLHS(0,9)+=gauss_weight*(DN_v(0,0)*crLHS90 + DN_v(0,1)*crLHS92 - crLHS16*crLHS94 - crLHS19*crLHS94 + crLHS93); + rLHS(0,10)+=gauss_weight*(DN_v(0,0)*crLHS95 + DN_v(0,1)*crLHS97 - crLHS103*crLHS16 - crLHS103*crLHS19 + crLHS105 + crLHS98); + rLHS(0,11)+=gauss_weight*(DN_v(0,0)*crLHS106 + DN_v(0,1)*crLHS108 + crLHS109 - crLHS110*crLHS16 - crLHS110*crLHS19); + rLHS(0,12)+=gauss_weight*(crLHS10*crLHS112 + crLHS111 + crLHS112*crLHS18); + rLHS(0,13)+=gauss_weight*(crLHS10*crLHS114 + crLHS113 + crLHS114*crLHS18); + rLHS(0,14)+=gauss_weight*(crLHS10*crLHS116 + crLHS115 + crLHS116*crLHS18); + rLHS(1,0)+=gauss_weight*(DN_v(0,0)*crLHS2 + DN_v(0,1)*crLHS117 - crLHS119*crLHS16 - crLHS119*crLHS19 + crLHS25); + rLHS(1,1)+=gauss_weight*(DN_v(0,0)*crLHS23 + std::pow(DN_v(0,1), 2)*crLHS6 + DN_v(0,1)*crLHS120 - crLHS123*crLHS16 - crLHS123*crLHS19 + crLHS20); + rLHS(1,2)+=gauss_weight*(DN_v(0,0)*crLHS29 + DN_v(0,1)*crLHS124 + crLHS126 - crLHS128*crLHS16 - crLHS128*crLHS19); + rLHS(1,3)+=gauss_weight*(DN_v(0,0)*crLHS41 + DN_v(0,1)*crLHS129 + crLHS130 - crLHS132*crLHS16 - crLHS132*crLHS19 + crLHS38); + rLHS(1,4)+=gauss_weight*(DN_v(0,0)*crLHS46 + DN_v(0,1)*crLHS133 + crLHS134 - crLHS136*crLHS16 - crLHS136*crLHS19); + rLHS(1,5)+=gauss_weight*(DN_v(0,0)*crLHS58 + DN_v(0,1)*crLHS137 + crLHS138 - crLHS140*crLHS16 - crLHS140*crLHS19 + crLHS55); + rLHS(1,6)+=gauss_weight*(DN_v(0,0)*crLHS63 + DN_v(0,1)*crLHS141 + crLHS142 - crLHS144*crLHS16 - crLHS144*crLHS19); + rLHS(1,7)+=gauss_weight*(DN_v(0,0)*crLHS75 + DN_v(0,1)*crLHS145 + crLHS146 - crLHS148*crLHS16 - crLHS148*crLHS19 + crLHS72); + rLHS(1,8)+=gauss_weight*(DN_v(0,0)*crLHS80 + DN_v(0,1)*crLHS149 + crLHS150 - crLHS152*crLHS16 - crLHS152*crLHS19); + rLHS(1,9)+=gauss_weight*(DN_v(0,0)*crLHS92 + DN_v(0,1)*crLHS153 + crLHS154 - crLHS156*crLHS16 - crLHS156*crLHS19 + crLHS89); + rLHS(1,10)+=gauss_weight*(DN_v(0,0)*crLHS97 + DN_v(0,1)*crLHS157 + crLHS158 - crLHS16*crLHS160 - crLHS160*crLHS19); + rLHS(1,11)+=gauss_weight*(DN_v(0,0)*crLHS108 + DN_v(0,1)*crLHS161 + crLHS105 - crLHS16*crLHS164 + crLHS162 - crLHS164*crLHS19); + rLHS(1,12)+=gauss_weight*(crLHS10*crLHS166 + crLHS165 + crLHS166*crLHS18); + rLHS(1,13)+=gauss_weight*(crLHS10*crLHS168 + crLHS167 + crLHS168*crLHS18); + rLHS(1,14)+=gauss_weight*(crLHS10*crLHS170 + crLHS169 + crLHS170*crLHS18); + rLHS(2,0)+=gauss_weight*(DN_v(1,0)*crLHS0 + DN_v(1,1)*crLHS2 - crLHS14*crLHS171 - crLHS14*crLHS173 + crLHS174 + crLHS30); + rLHS(2,1)+=gauss_weight*(DN_v(1,0)*crLHS21 + DN_v(1,1)*crLHS23 + crLHS126 - crLHS171*crLHS26 - crLHS173*crLHS26); + rLHS(2,2)+=gauss_weight*(std::pow(DN_v(1,0), 2)*crLHS6 + DN_v(1,0)*crLHS27 + DN_v(1,1)*crLHS29 - crLHS171*crLHS36 - crLHS173*crLHS36 + crLHS175); + rLHS(2,3)+=gauss_weight*(DN_v(1,0)*crLHS39 + DN_v(1,1)*crLHS41 - crLHS171*crLHS43 - crLHS173*crLHS43 + crLHS177); + rLHS(2,4)+=gauss_weight*(DN_v(1,0)*crLHS44 + DN_v(1,1)*crLHS46 - crLHS171*crLHS53 - crLHS173*crLHS53 + crLHS178 + crLHS180); + rLHS(2,5)+=gauss_weight*(DN_v(1,0)*crLHS56 + DN_v(1,1)*crLHS58 - crLHS171*crLHS60 - crLHS173*crLHS60 + crLHS181); + rLHS(2,6)+=gauss_weight*(DN_v(1,0)*crLHS61 + DN_v(1,1)*crLHS63 - crLHS171*crLHS70 - crLHS173*crLHS70 + crLHS182 + crLHS184); + rLHS(2,7)+=gauss_weight*(DN_v(1,0)*crLHS73 + DN_v(1,1)*crLHS75 - crLHS171*crLHS77 - crLHS173*crLHS77 + crLHS185); + rLHS(2,8)+=gauss_weight*(DN_v(1,0)*crLHS78 + DN_v(1,1)*crLHS80 - crLHS171*crLHS87 - crLHS173*crLHS87 + crLHS186 + crLHS188); + rLHS(2,9)+=gauss_weight*(DN_v(1,0)*crLHS90 + DN_v(1,1)*crLHS92 - crLHS171*crLHS94 - crLHS173*crLHS94 + crLHS189); + rLHS(2,10)+=gauss_weight*(DN_v(1,0)*crLHS95 + DN_v(1,1)*crLHS97 - crLHS103*crLHS171 - crLHS103*crLHS173 + crLHS190 + crLHS192); + rLHS(2,11)+=gauss_weight*(DN_v(1,0)*crLHS106 + DN_v(1,1)*crLHS108 - crLHS110*crLHS171 - crLHS110*crLHS173 + crLHS193); + rLHS(2,12)+=gauss_weight*(crLHS112*crLHS172 + crLHS112*crLHS33 + crLHS194); + rLHS(2,13)+=gauss_weight*(crLHS114*crLHS172 + crLHS114*crLHS33 + crLHS195); + rLHS(2,14)+=gauss_weight*(crLHS116*crLHS172 + crLHS116*crLHS33 + crLHS196); + rLHS(3,0)+=gauss_weight*(DN_v(1,0)*crLHS2 + DN_v(1,1)*crLHS117 - crLHS119*crLHS171 - crLHS119*crLHS173 + crLHS42); + rLHS(3,1)+=gauss_weight*(DN_v(1,0)*crLHS23 + DN_v(1,1)*crLHS120 - crLHS123*crLHS171 - crLHS123*crLHS173 + crLHS130 + crLHS174); + rLHS(3,2)+=gauss_weight*(DN_v(1,0)*crLHS29 + DN_v(1,1)*crLHS124 - crLHS128*crLHS171 - crLHS128*crLHS173 + crLHS177); + rLHS(3,3)+=gauss_weight*(DN_v(1,0)*crLHS41 + std::pow(DN_v(1,1), 2)*crLHS6 + DN_v(1,1)*crLHS129 - crLHS132*crLHS171 - crLHS132*crLHS173 + crLHS175); + rLHS(3,4)+=gauss_weight*(DN_v(1,0)*crLHS46 + DN_v(1,1)*crLHS133 - crLHS136*crLHS171 - crLHS136*crLHS173 + crLHS198); + rLHS(3,5)+=gauss_weight*(DN_v(1,0)*crLHS58 + DN_v(1,1)*crLHS137 - crLHS140*crLHS171 - crLHS140*crLHS173 + crLHS180 + crLHS199); + rLHS(3,6)+=gauss_weight*(DN_v(1,0)*crLHS63 + DN_v(1,1)*crLHS141 - crLHS144*crLHS171 - crLHS144*crLHS173 + crLHS200); + rLHS(3,7)+=gauss_weight*(DN_v(1,0)*crLHS75 + DN_v(1,1)*crLHS145 - crLHS148*crLHS171 - crLHS148*crLHS173 + crLHS184 + crLHS201); + rLHS(3,8)+=gauss_weight*(DN_v(1,0)*crLHS80 + DN_v(1,1)*crLHS149 - crLHS152*crLHS171 - crLHS152*crLHS173 + crLHS202); + rLHS(3,9)+=gauss_weight*(DN_v(1,0)*crLHS92 + DN_v(1,1)*crLHS153 - crLHS156*crLHS171 - crLHS156*crLHS173 + crLHS188 + crLHS203); + rLHS(3,10)+=gauss_weight*(DN_v(1,0)*crLHS97 + DN_v(1,1)*crLHS157 - crLHS160*crLHS171 - crLHS160*crLHS173 + crLHS204); + rLHS(3,11)+=gauss_weight*(DN_v(1,0)*crLHS108 + DN_v(1,1)*crLHS161 - crLHS164*crLHS171 - crLHS164*crLHS173 + crLHS192 + crLHS205); + rLHS(3,12)+=gauss_weight*(crLHS166*crLHS172 + crLHS166*crLHS33 + crLHS206); + rLHS(3,13)+=gauss_weight*(crLHS168*crLHS172 + crLHS168*crLHS33 + crLHS207); + rLHS(3,14)+=gauss_weight*(crLHS170*crLHS172 + crLHS170*crLHS33 + crLHS208); + rLHS(4,0)+=gauss_weight*(DN_v(2,0)*crLHS0 + DN_v(2,1)*crLHS2 - crLHS14*crLHS209 - crLHS14*crLHS211 + crLHS212 + crLHS47); + rLHS(4,1)+=gauss_weight*(DN_v(2,0)*crLHS21 + DN_v(2,1)*crLHS23 + crLHS134 - crLHS209*crLHS26 - crLHS211*crLHS26); + rLHS(4,2)+=gauss_weight*(DN_v(2,0)*crLHS27 + DN_v(2,1)*crLHS29 + crLHS178 - crLHS209*crLHS36 - crLHS211*crLHS36 + crLHS213); + rLHS(4,3)+=gauss_weight*(DN_v(2,0)*crLHS39 + DN_v(2,1)*crLHS41 + crLHS198 - crLHS209*crLHS43 - crLHS211*crLHS43); + rLHS(4,4)+=gauss_weight*(std::pow(DN_v(2,0), 2)*crLHS6 + DN_v(2,0)*crLHS44 + DN_v(2,1)*crLHS46 - crLHS209*crLHS53 - crLHS211*crLHS53 + crLHS214); + rLHS(4,5)+=gauss_weight*(DN_v(2,0)*crLHS56 + DN_v(2,1)*crLHS58 - crLHS209*crLHS60 - crLHS211*crLHS60 + crLHS216); + rLHS(4,6)+=gauss_weight*(DN_v(2,0)*crLHS61 + DN_v(2,1)*crLHS63 - crLHS209*crLHS70 - crLHS211*crLHS70 + crLHS217 + crLHS219); + rLHS(4,7)+=gauss_weight*(DN_v(2,0)*crLHS73 + DN_v(2,1)*crLHS75 - crLHS209*crLHS77 - crLHS211*crLHS77 + crLHS220); + rLHS(4,8)+=gauss_weight*(DN_v(2,0)*crLHS78 + DN_v(2,1)*crLHS80 - crLHS209*crLHS87 - crLHS211*crLHS87 + crLHS221 + crLHS223); + rLHS(4,9)+=gauss_weight*(DN_v(2,0)*crLHS90 + DN_v(2,1)*crLHS92 - crLHS209*crLHS94 - crLHS211*crLHS94 + crLHS224); + rLHS(4,10)+=gauss_weight*(DN_v(2,0)*crLHS95 + DN_v(2,1)*crLHS97 - crLHS103*crLHS209 - crLHS103*crLHS211 + crLHS225 + crLHS227); + rLHS(4,11)+=gauss_weight*(DN_v(2,0)*crLHS106 + DN_v(2,1)*crLHS108 - crLHS110*crLHS209 - crLHS110*crLHS211 + crLHS228); + rLHS(4,12)+=gauss_weight*(crLHS112*crLHS210 + crLHS112*crLHS50 + crLHS229); + rLHS(4,13)+=gauss_weight*(crLHS114*crLHS210 + crLHS114*crLHS50 + crLHS230); + rLHS(4,14)+=gauss_weight*(crLHS116*crLHS210 + crLHS116*crLHS50 + crLHS231); + rLHS(5,0)+=gauss_weight*(DN_v(2,0)*crLHS2 + DN_v(2,1)*crLHS117 - crLHS119*crLHS209 - crLHS119*crLHS211 + crLHS59); + rLHS(5,1)+=gauss_weight*(DN_v(2,0)*crLHS23 + DN_v(2,1)*crLHS120 - crLHS123*crLHS209 - crLHS123*crLHS211 + crLHS138 + crLHS212); + rLHS(5,2)+=gauss_weight*(DN_v(2,0)*crLHS29 + DN_v(2,1)*crLHS124 - crLHS128*crLHS209 - crLHS128*crLHS211 + crLHS181); + rLHS(5,3)+=gauss_weight*(DN_v(2,0)*crLHS41 + DN_v(2,1)*crLHS129 - crLHS132*crLHS209 - crLHS132*crLHS211 + crLHS199 + crLHS213); + rLHS(5,4)+=gauss_weight*(DN_v(2,0)*crLHS46 + DN_v(2,1)*crLHS133 - crLHS136*crLHS209 - crLHS136*crLHS211 + crLHS216); + rLHS(5,5)+=gauss_weight*(DN_v(2,0)*crLHS58 + std::pow(DN_v(2,1), 2)*crLHS6 + DN_v(2,1)*crLHS137 - crLHS140*crLHS209 - crLHS140*crLHS211 + crLHS214); + rLHS(5,6)+=gauss_weight*(DN_v(2,0)*crLHS63 + DN_v(2,1)*crLHS141 - crLHS144*crLHS209 - crLHS144*crLHS211 + crLHS233); + rLHS(5,7)+=gauss_weight*(DN_v(2,0)*crLHS75 + DN_v(2,1)*crLHS145 - crLHS148*crLHS209 - crLHS148*crLHS211 + crLHS219 + crLHS234); + rLHS(5,8)+=gauss_weight*(DN_v(2,0)*crLHS80 + DN_v(2,1)*crLHS149 - crLHS152*crLHS209 - crLHS152*crLHS211 + crLHS235); + rLHS(5,9)+=gauss_weight*(DN_v(2,0)*crLHS92 + DN_v(2,1)*crLHS153 - crLHS156*crLHS209 - crLHS156*crLHS211 + crLHS223 + crLHS236); + rLHS(5,10)+=gauss_weight*(DN_v(2,0)*crLHS97 + DN_v(2,1)*crLHS157 - crLHS160*crLHS209 - crLHS160*crLHS211 + crLHS237); + rLHS(5,11)+=gauss_weight*(DN_v(2,0)*crLHS108 + DN_v(2,1)*crLHS161 - crLHS164*crLHS209 - crLHS164*crLHS211 + crLHS227 + crLHS238); + rLHS(5,12)+=gauss_weight*(crLHS166*crLHS210 + crLHS166*crLHS50 + crLHS239); + rLHS(5,13)+=gauss_weight*(crLHS168*crLHS210 + crLHS168*crLHS50 + crLHS240); + rLHS(5,14)+=gauss_weight*(crLHS170*crLHS210 + crLHS170*crLHS50 + crLHS241); + rLHS(6,0)+=gauss_weight*(DN_v(3,0)*crLHS0 + DN_v(3,1)*crLHS2 - crLHS14*crLHS242 - crLHS14*crLHS244 + crLHS245 + crLHS64); + rLHS(6,1)+=gauss_weight*(DN_v(3,0)*crLHS21 + DN_v(3,1)*crLHS23 + crLHS142 - crLHS242*crLHS26 - crLHS244*crLHS26); + rLHS(6,2)+=gauss_weight*(DN_v(3,0)*crLHS27 + DN_v(3,1)*crLHS29 + crLHS182 - crLHS242*crLHS36 - crLHS244*crLHS36 + crLHS246); + rLHS(6,3)+=gauss_weight*(DN_v(3,0)*crLHS39 + DN_v(3,1)*crLHS41 + crLHS200 - crLHS242*crLHS43 - crLHS244*crLHS43); + rLHS(6,4)+=gauss_weight*(DN_v(3,0)*crLHS44 + DN_v(3,1)*crLHS46 + crLHS217 - crLHS242*crLHS53 - crLHS244*crLHS53 + crLHS247); + rLHS(6,5)+=gauss_weight*(DN_v(3,0)*crLHS56 + DN_v(3,1)*crLHS58 + crLHS233 - crLHS242*crLHS60 - crLHS244*crLHS60); + rLHS(6,6)+=gauss_weight*(std::pow(DN_v(3,0), 2)*crLHS6 + DN_v(3,0)*crLHS61 + DN_v(3,1)*crLHS63 - crLHS242*crLHS70 - crLHS244*crLHS70 + crLHS248); + rLHS(6,7)+=gauss_weight*(DN_v(3,0)*crLHS73 + DN_v(3,1)*crLHS75 - crLHS242*crLHS77 - crLHS244*crLHS77 + crLHS250); + rLHS(6,8)+=gauss_weight*(DN_v(3,0)*crLHS78 + DN_v(3,1)*crLHS80 - crLHS242*crLHS87 - crLHS244*crLHS87 + crLHS251 + crLHS253); + rLHS(6,9)+=gauss_weight*(DN_v(3,0)*crLHS90 + DN_v(3,1)*crLHS92 - crLHS242*crLHS94 - crLHS244*crLHS94 + crLHS254); + rLHS(6,10)+=gauss_weight*(DN_v(3,0)*crLHS95 + DN_v(3,1)*crLHS97 - crLHS103*crLHS242 - crLHS103*crLHS244 + crLHS255 + crLHS257); + rLHS(6,11)+=gauss_weight*(DN_v(3,0)*crLHS106 + DN_v(3,1)*crLHS108 - crLHS110*crLHS242 - crLHS110*crLHS244 + crLHS258); + rLHS(6,12)+=gauss_weight*(crLHS112*crLHS243 + crLHS112*crLHS67 + crLHS259); + rLHS(6,13)+=gauss_weight*(crLHS114*crLHS243 + crLHS114*crLHS67 + crLHS260); + rLHS(6,14)+=gauss_weight*(crLHS116*crLHS243 + crLHS116*crLHS67 + crLHS261); + rLHS(7,0)+=gauss_weight*(DN_v(3,0)*crLHS2 + DN_v(3,1)*crLHS117 - crLHS119*crLHS242 - crLHS119*crLHS244 + crLHS76); + rLHS(7,1)+=gauss_weight*(DN_v(3,0)*crLHS23 + DN_v(3,1)*crLHS120 - crLHS123*crLHS242 - crLHS123*crLHS244 + crLHS146 + crLHS245); + rLHS(7,2)+=gauss_weight*(DN_v(3,0)*crLHS29 + DN_v(3,1)*crLHS124 - crLHS128*crLHS242 - crLHS128*crLHS244 + crLHS185); + rLHS(7,3)+=gauss_weight*(DN_v(3,0)*crLHS41 + DN_v(3,1)*crLHS129 - crLHS132*crLHS242 - crLHS132*crLHS244 + crLHS201 + crLHS246); + rLHS(7,4)+=gauss_weight*(DN_v(3,0)*crLHS46 + DN_v(3,1)*crLHS133 - crLHS136*crLHS242 - crLHS136*crLHS244 + crLHS220); + rLHS(7,5)+=gauss_weight*(DN_v(3,0)*crLHS58 + DN_v(3,1)*crLHS137 - crLHS140*crLHS242 - crLHS140*crLHS244 + crLHS234 + crLHS247); + rLHS(7,6)+=gauss_weight*(DN_v(3,0)*crLHS63 + DN_v(3,1)*crLHS141 - crLHS144*crLHS242 - crLHS144*crLHS244 + crLHS250); + rLHS(7,7)+=gauss_weight*(DN_v(3,0)*crLHS75 + std::pow(DN_v(3,1), 2)*crLHS6 + DN_v(3,1)*crLHS145 - crLHS148*crLHS242 - crLHS148*crLHS244 + crLHS248); + rLHS(7,8)+=gauss_weight*(DN_v(3,0)*crLHS80 + DN_v(3,1)*crLHS149 - crLHS152*crLHS242 - crLHS152*crLHS244 + crLHS263); + rLHS(7,9)+=gauss_weight*(DN_v(3,0)*crLHS92 + DN_v(3,1)*crLHS153 - crLHS156*crLHS242 - crLHS156*crLHS244 + crLHS253 + crLHS264); + rLHS(7,10)+=gauss_weight*(DN_v(3,0)*crLHS97 + DN_v(3,1)*crLHS157 - crLHS160*crLHS242 - crLHS160*crLHS244 + crLHS265); + rLHS(7,11)+=gauss_weight*(DN_v(3,0)*crLHS108 + DN_v(3,1)*crLHS161 - crLHS164*crLHS242 - crLHS164*crLHS244 + crLHS257 + crLHS266); + rLHS(7,12)+=gauss_weight*(crLHS166*crLHS243 + crLHS166*crLHS67 + crLHS267); + rLHS(7,13)+=gauss_weight*(crLHS168*crLHS243 + crLHS168*crLHS67 + crLHS268); + rLHS(7,14)+=gauss_weight*(crLHS170*crLHS243 + crLHS170*crLHS67 + crLHS269); + rLHS(8,0)+=gauss_weight*(DN_v(4,0)*crLHS0 + DN_v(4,1)*crLHS2 - crLHS14*crLHS270 - crLHS14*crLHS272 + crLHS273 + crLHS81); + rLHS(8,1)+=gauss_weight*(DN_v(4,0)*crLHS21 + DN_v(4,1)*crLHS23 + crLHS150 - crLHS26*crLHS270 - crLHS26*crLHS272); + rLHS(8,2)+=gauss_weight*(DN_v(4,0)*crLHS27 + DN_v(4,1)*crLHS29 + crLHS186 - crLHS270*crLHS36 - crLHS272*crLHS36 + crLHS274); + rLHS(8,3)+=gauss_weight*(DN_v(4,0)*crLHS39 + DN_v(4,1)*crLHS41 + crLHS202 - crLHS270*crLHS43 - crLHS272*crLHS43); + rLHS(8,4)+=gauss_weight*(DN_v(4,0)*crLHS44 + DN_v(4,1)*crLHS46 + crLHS221 - crLHS270*crLHS53 - crLHS272*crLHS53 + crLHS275); + rLHS(8,5)+=gauss_weight*(DN_v(4,0)*crLHS56 + DN_v(4,1)*crLHS58 + crLHS235 - crLHS270*crLHS60 - crLHS272*crLHS60); + rLHS(8,6)+=gauss_weight*(DN_v(4,0)*crLHS61 + DN_v(4,1)*crLHS63 + crLHS251 - crLHS270*crLHS70 - crLHS272*crLHS70 + crLHS276); + rLHS(8,7)+=gauss_weight*(DN_v(4,0)*crLHS73 + DN_v(4,1)*crLHS75 + crLHS263 - crLHS270*crLHS77 - crLHS272*crLHS77); + rLHS(8,8)+=gauss_weight*(std::pow(DN_v(4,0), 2)*crLHS6 + DN_v(4,0)*crLHS78 + DN_v(4,1)*crLHS80 - crLHS270*crLHS87 - crLHS272*crLHS87 + crLHS277); + rLHS(8,9)+=gauss_weight*(DN_v(4,0)*crLHS90 + DN_v(4,1)*crLHS92 - crLHS270*crLHS94 - crLHS272*crLHS94 + crLHS279); + rLHS(8,10)+=gauss_weight*(DN_v(4,0)*crLHS95 + DN_v(4,1)*crLHS97 - crLHS103*crLHS270 - crLHS103*crLHS272 + crLHS280 + crLHS282); + rLHS(8,11)+=gauss_weight*(DN_v(4,0)*crLHS106 + DN_v(4,1)*crLHS108 - crLHS110*crLHS270 - crLHS110*crLHS272 + crLHS283); + rLHS(8,12)+=gauss_weight*(crLHS112*crLHS271 + crLHS112*crLHS84 + crLHS284); + rLHS(8,13)+=gauss_weight*(crLHS114*crLHS271 + crLHS114*crLHS84 + crLHS285); + rLHS(8,14)+=gauss_weight*(crLHS116*crLHS271 + crLHS116*crLHS84 + crLHS286); + rLHS(9,0)+=gauss_weight*(DN_v(4,0)*crLHS2 + DN_v(4,1)*crLHS117 - crLHS119*crLHS270 - crLHS119*crLHS272 + crLHS93); + rLHS(9,1)+=gauss_weight*(DN_v(4,0)*crLHS23 + DN_v(4,1)*crLHS120 - crLHS123*crLHS270 - crLHS123*crLHS272 + crLHS154 + crLHS273); + rLHS(9,2)+=gauss_weight*(DN_v(4,0)*crLHS29 + DN_v(4,1)*crLHS124 - crLHS128*crLHS270 - crLHS128*crLHS272 + crLHS189); + rLHS(9,3)+=gauss_weight*(DN_v(4,0)*crLHS41 + DN_v(4,1)*crLHS129 - crLHS132*crLHS270 - crLHS132*crLHS272 + crLHS203 + crLHS274); + rLHS(9,4)+=gauss_weight*(DN_v(4,0)*crLHS46 + DN_v(4,1)*crLHS133 - crLHS136*crLHS270 - crLHS136*crLHS272 + crLHS224); + rLHS(9,5)+=gauss_weight*(DN_v(4,0)*crLHS58 + DN_v(4,1)*crLHS137 - crLHS140*crLHS270 - crLHS140*crLHS272 + crLHS236 + crLHS275); + rLHS(9,6)+=gauss_weight*(DN_v(4,0)*crLHS63 + DN_v(4,1)*crLHS141 - crLHS144*crLHS270 - crLHS144*crLHS272 + crLHS254); + rLHS(9,7)+=gauss_weight*(DN_v(4,0)*crLHS75 + DN_v(4,1)*crLHS145 - crLHS148*crLHS270 - crLHS148*crLHS272 + crLHS264 + crLHS276); + rLHS(9,8)+=gauss_weight*(DN_v(4,0)*crLHS80 + DN_v(4,1)*crLHS149 - crLHS152*crLHS270 - crLHS152*crLHS272 + crLHS279); + rLHS(9,9)+=gauss_weight*(DN_v(4,0)*crLHS92 + std::pow(DN_v(4,1), 2)*crLHS6 + DN_v(4,1)*crLHS153 - crLHS156*crLHS270 - crLHS156*crLHS272 + crLHS277); + rLHS(9,10)+=gauss_weight*(DN_v(4,0)*crLHS97 + DN_v(4,1)*crLHS157 - crLHS160*crLHS270 - crLHS160*crLHS272 + crLHS288); + rLHS(9,11)+=gauss_weight*(DN_v(4,0)*crLHS108 + DN_v(4,1)*crLHS161 - crLHS164*crLHS270 - crLHS164*crLHS272 + crLHS282 + crLHS289); + rLHS(9,12)+=gauss_weight*(crLHS166*crLHS271 + crLHS166*crLHS84 + crLHS290); + rLHS(9,13)+=gauss_weight*(crLHS168*crLHS271 + crLHS168*crLHS84 + crLHS291); + rLHS(9,14)+=gauss_weight*(crLHS170*crLHS271 + crLHS170*crLHS84 + crLHS292); + rLHS(10,0)+=gauss_weight*(DN_v(5,0)*crLHS0 + DN_v(5,1)*crLHS2 - crLHS14*crLHS293 - crLHS14*crLHS295 + crLHS296 + crLHS98); + rLHS(10,1)+=gauss_weight*(DN_v(5,0)*crLHS21 + DN_v(5,1)*crLHS23 + crLHS158 - crLHS26*crLHS293 - crLHS26*crLHS295); + rLHS(10,2)+=gauss_weight*(DN_v(5,0)*crLHS27 + DN_v(5,1)*crLHS29 + crLHS190 - crLHS293*crLHS36 - crLHS295*crLHS36 + crLHS297); + rLHS(10,3)+=gauss_weight*(DN_v(5,0)*crLHS39 + DN_v(5,1)*crLHS41 + crLHS204 - crLHS293*crLHS43 - crLHS295*crLHS43); + rLHS(10,4)+=gauss_weight*(DN_v(5,0)*crLHS44 + DN_v(5,1)*crLHS46 + crLHS225 - crLHS293*crLHS53 - crLHS295*crLHS53 + crLHS298); + rLHS(10,5)+=gauss_weight*(DN_v(5,0)*crLHS56 + DN_v(5,1)*crLHS58 + crLHS237 - crLHS293*crLHS60 - crLHS295*crLHS60); + rLHS(10,6)+=gauss_weight*(DN_v(5,0)*crLHS61 + DN_v(5,1)*crLHS63 + crLHS255 - crLHS293*crLHS70 - crLHS295*crLHS70 + crLHS299); + rLHS(10,7)+=gauss_weight*(DN_v(5,0)*crLHS73 + DN_v(5,1)*crLHS75 + crLHS265 - crLHS293*crLHS77 - crLHS295*crLHS77); + rLHS(10,8)+=gauss_weight*(DN_v(5,0)*crLHS78 + DN_v(5,1)*crLHS80 + crLHS280 - crLHS293*crLHS87 - crLHS295*crLHS87 + crLHS300); + rLHS(10,9)+=gauss_weight*(DN_v(5,0)*crLHS90 + DN_v(5,1)*crLHS92 + crLHS288 - crLHS293*crLHS94 - crLHS295*crLHS94); + rLHS(10,10)+=gauss_weight*(std::pow(DN_v(5,0), 2)*crLHS6 + DN_v(5,0)*crLHS95 + DN_v(5,1)*crLHS97 - crLHS103*crLHS293 - crLHS103*crLHS295 + crLHS301); + rLHS(10,11)+=gauss_weight*(DN_v(5,0)*crLHS106 + DN_v(5,1)*crLHS108 - crLHS110*crLHS293 - crLHS110*crLHS295 + crLHS302); + rLHS(10,12)+=gauss_weight*(crLHS101*crLHS112 + crLHS112*crLHS294 + crLHS303); + rLHS(10,13)+=gauss_weight*(crLHS101*crLHS114 + crLHS114*crLHS294 + crLHS304); + rLHS(10,14)+=gauss_weight*(crLHS101*crLHS116 + crLHS116*crLHS294 + crLHS305); + rLHS(11,0)+=gauss_weight*(DN_v(5,0)*crLHS2 + DN_v(5,1)*crLHS117 + crLHS109 - crLHS119*crLHS293 - crLHS119*crLHS295); + rLHS(11,1)+=gauss_weight*(DN_v(5,0)*crLHS23 + DN_v(5,1)*crLHS120 - crLHS123*crLHS293 - crLHS123*crLHS295 + crLHS162 + crLHS296); + rLHS(11,2)+=gauss_weight*(DN_v(5,0)*crLHS29 + DN_v(5,1)*crLHS124 - crLHS128*crLHS293 - crLHS128*crLHS295 + crLHS193); + rLHS(11,3)+=gauss_weight*(DN_v(5,0)*crLHS41 + DN_v(5,1)*crLHS129 - crLHS132*crLHS293 - crLHS132*crLHS295 + crLHS205 + crLHS297); + rLHS(11,4)+=gauss_weight*(DN_v(5,0)*crLHS46 + DN_v(5,1)*crLHS133 - crLHS136*crLHS293 - crLHS136*crLHS295 + crLHS228); + rLHS(11,5)+=gauss_weight*(DN_v(5,0)*crLHS58 + DN_v(5,1)*crLHS137 - crLHS140*crLHS293 - crLHS140*crLHS295 + crLHS238 + crLHS298); + rLHS(11,6)+=gauss_weight*(DN_v(5,0)*crLHS63 + DN_v(5,1)*crLHS141 - crLHS144*crLHS293 - crLHS144*crLHS295 + crLHS258); + rLHS(11,7)+=gauss_weight*(DN_v(5,0)*crLHS75 + DN_v(5,1)*crLHS145 - crLHS148*crLHS293 - crLHS148*crLHS295 + crLHS266 + crLHS299); + rLHS(11,8)+=gauss_weight*(DN_v(5,0)*crLHS80 + DN_v(5,1)*crLHS149 - crLHS152*crLHS293 - crLHS152*crLHS295 + crLHS283); + rLHS(11,9)+=gauss_weight*(DN_v(5,0)*crLHS92 + DN_v(5,1)*crLHS153 - crLHS156*crLHS293 - crLHS156*crLHS295 + crLHS289 + crLHS300); + rLHS(11,10)+=gauss_weight*(DN_v(5,0)*crLHS97 + DN_v(5,1)*crLHS157 - crLHS160*crLHS293 - crLHS160*crLHS295 + crLHS302); + rLHS(11,11)+=gauss_weight*(DN_v(5,0)*crLHS108 + std::pow(DN_v(5,1), 2)*crLHS6 + DN_v(5,1)*crLHS161 - crLHS164*crLHS293 - crLHS164*crLHS295 + crLHS301); + rLHS(11,12)+=gauss_weight*(crLHS101*crLHS166 + crLHS166*crLHS294 + crLHS306); + rLHS(11,13)+=gauss_weight*(crLHS101*crLHS168 + crLHS168*crLHS294 + crLHS307); + rLHS(11,14)+=gauss_weight*(crLHS101*crLHS170 + crLHS170*crLHS294 + crLHS308); + rLHS(12,0)+=-gauss_weight*(crLHS111 + crLHS112*crLHS14 + crLHS119*crLHS166); + rLHS(12,1)+=-gauss_weight*(crLHS112*crLHS26 + crLHS123*crLHS166 + crLHS165); + rLHS(12,2)+=-gauss_weight*(crLHS112*crLHS36 + crLHS128*crLHS166 + crLHS194); + rLHS(12,3)+=-gauss_weight*(crLHS112*crLHS43 + crLHS132*crLHS166 + crLHS206); + rLHS(12,4)+=-gauss_weight*(crLHS112*crLHS53 + crLHS136*crLHS166 + crLHS229); + rLHS(12,5)+=-gauss_weight*(crLHS112*crLHS60 + crLHS140*crLHS166 + crLHS239); + rLHS(12,6)+=-gauss_weight*(crLHS112*crLHS70 + crLHS144*crLHS166 + crLHS259); + rLHS(12,7)+=-gauss_weight*(crLHS112*crLHS77 + crLHS148*crLHS166 + crLHS267); + rLHS(12,8)+=-gauss_weight*(crLHS112*crLHS87 + crLHS152*crLHS166 + crLHS284); + rLHS(12,9)+=-gauss_weight*(crLHS112*crLHS94 + crLHS156*crLHS166 + crLHS290); + rLHS(12,10)+=-gauss_weight*(crLHS103*crLHS112 + crLHS160*crLHS166 + crLHS303); + rLHS(12,11)+=-gauss_weight*(crLHS110*crLHS112 + crLHS164*crLHS166 + crLHS306); + rLHS(12,12)+=crLHS309*(std::pow(DN_p(0,0), 2) + std::pow(DN_p(0,1), 2)); + rLHS(12,13)+=crLHS310; + rLHS(12,14)+=crLHS311; + rLHS(13,0)+=-gauss_weight*(crLHS113 + crLHS114*crLHS14 + crLHS119*crLHS168); + rLHS(13,1)+=-gauss_weight*(crLHS114*crLHS26 + crLHS123*crLHS168 + crLHS167); + rLHS(13,2)+=-gauss_weight*(crLHS114*crLHS36 + crLHS128*crLHS168 + crLHS195); + rLHS(13,3)+=-gauss_weight*(crLHS114*crLHS43 + crLHS132*crLHS168 + crLHS207); + rLHS(13,4)+=-gauss_weight*(crLHS114*crLHS53 + crLHS136*crLHS168 + crLHS230); + rLHS(13,5)+=-gauss_weight*(crLHS114*crLHS60 + crLHS140*crLHS168 + crLHS240); + rLHS(13,6)+=-gauss_weight*(crLHS114*crLHS70 + crLHS144*crLHS168 + crLHS260); + rLHS(13,7)+=-gauss_weight*(crLHS114*crLHS77 + crLHS148*crLHS168 + crLHS268); + rLHS(13,8)+=-gauss_weight*(crLHS114*crLHS87 + crLHS152*crLHS168 + crLHS285); + rLHS(13,9)+=-gauss_weight*(crLHS114*crLHS94 + crLHS156*crLHS168 + crLHS291); + rLHS(13,10)+=-gauss_weight*(crLHS103*crLHS114 + crLHS160*crLHS168 + crLHS304); + rLHS(13,11)+=-gauss_weight*(crLHS110*crLHS114 + crLHS164*crLHS168 + crLHS307); + rLHS(13,12)+=crLHS310; + rLHS(13,13)+=crLHS309*(std::pow(DN_p(1,0), 2) + std::pow(DN_p(1,1), 2)); + rLHS(13,14)+=crLHS312; + rLHS(14,0)+=-gauss_weight*(crLHS115 + crLHS116*crLHS14 + crLHS119*crLHS170); + rLHS(14,1)+=-gauss_weight*(crLHS116*crLHS26 + crLHS123*crLHS170 + crLHS169); + rLHS(14,2)+=-gauss_weight*(crLHS116*crLHS36 + crLHS128*crLHS170 + crLHS196); + rLHS(14,3)+=-gauss_weight*(crLHS116*crLHS43 + crLHS132*crLHS170 + crLHS208); + rLHS(14,4)+=-gauss_weight*(crLHS116*crLHS53 + crLHS136*crLHS170 + crLHS231); + rLHS(14,5)+=-gauss_weight*(crLHS116*crLHS60 + crLHS140*crLHS170 + crLHS241); + rLHS(14,6)+=-gauss_weight*(crLHS116*crLHS70 + crLHS144*crLHS170 + crLHS261); + rLHS(14,7)+=-gauss_weight*(crLHS116*crLHS77 + crLHS148*crLHS170 + crLHS269); + rLHS(14,8)+=-gauss_weight*(crLHS116*crLHS87 + crLHS152*crLHS170 + crLHS286); + rLHS(14,9)+=-gauss_weight*(crLHS116*crLHS94 + crLHS156*crLHS170 + crLHS292); + rLHS(14,10)+=-gauss_weight*(crLHS103*crLHS116 + crLHS160*crLHS170 + crLHS305); + rLHS(14,11)+=-gauss_weight*(crLHS110*crLHS116 + crLHS164*crLHS170 + crLHS308); + rLHS(14,12)+=crLHS311; + rLHS(14,13)+=crLHS312; + rLHS(14,14)+=crLHS309*(std::pow(DN_p(2,0), 2) + std::pow(DN_p(2,1), 2)); + +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<3>::AddGaussPointLeftHandSideContribution( + const ElementDataContainer& rData, + MatrixType& rLHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Calculate convective velocity + const BoundedMatrix vconv = rData.Velocity - rData.MeshVelocity; + + // Get constitutive matrix + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble LHS contribution + const double gauss_weight = rData.Weight; + const double crLHS0 = C(0,0)*DN_v(0,0) + C(0,3)*DN_v(0,1) + C(0,5)*DN_v(0,2); + const double crLHS1 = C(0,3)*DN_v(0,0); + const double crLHS2 = C(3,3)*DN_v(0,1) + C(3,5)*DN_v(0,2) + crLHS1; + const double crLHS3 = C(0,5)*DN_v(0,0); + const double crLHS4 = C(3,5)*DN_v(0,1) + C(5,5)*DN_v(0,2) + crLHS3; + const double crLHS5 = N_v[0]*vconv(0,0) + N_v[1]*vconv(1,0) + N_v[2]*vconv(2,0) + N_v[3]*vconv(3,0) + N_v[4]*vconv(4,0) + N_v[5]*vconv(5,0) + N_v[6]*vconv(6,0) + N_v[7]*vconv(7,0) + N_v[8]*vconv(8,0) + N_v[9]*vconv(9,0); + const double crLHS6 = N_v[0]*vconv(0,1) + N_v[1]*vconv(1,1) + N_v[2]*vconv(2,1) + N_v[3]*vconv(3,1) + N_v[4]*vconv(4,1) + N_v[5]*vconv(5,1) + N_v[6]*vconv(6,1) + N_v[7]*vconv(7,1) + N_v[8]*vconv(8,1) + N_v[9]*vconv(9,1); + const double crLHS7 = N_v[0]*vconv(0,2) + N_v[1]*vconv(1,2) + N_v[2]*vconv(2,2) + N_v[3]*vconv(3,2) + N_v[4]*vconv(4,2) + N_v[5]*vconv(5,2) + N_v[6]*vconv(6,2) + N_v[7]*vconv(7,2) + N_v[8]*vconv(8,2) + N_v[9]*vconv(9,2); + const double crLHS8 = rho*stab_c2*std::sqrt(std::pow(crLHS5, 2) + std::pow(crLHS6, 2) + std::pow(crLHS7, 2)); + const double crLHS9 = crLHS8*h/stab_c1 + mu; + const double crLHS10 = 1.0*C(0,0); + const double crLHS11 = C(0,3)*DDN_v[0](0,0); + const double crLHS12 = 1.0*DDN_v[0](0,1); + const double crLHS13 = C(0,5)*DDN_v[0](0,0); + const double crLHS14 = 1.0*DDN_v[0](0,2); + const double crLHS15 = rho*(DN_v(0,0)*crLHS5 + DN_v(0,1)*crLHS6 + DN_v(0,2)*crLHS7); + const double crLHS16 = rData.BDF0*rho; + const double crLHS17 = N_v[0]*crLHS16; + const double crLHS18 = -crLHS15 - crLHS17; + const double crLHS19 = C(0,3)*crLHS12 + C(0,5)*crLHS14 + C(3,3)*crLHS12 + C(3,5)*crLHS12 + C(3,5)*crLHS14 + C(5,5)*crLHS14 + DDN_v[0](0,0)*crLHS10 + 1.0*crLHS11 + 1.0*crLHS13 + crLHS18; + const double crLHS20 = 1.0/(crLHS8/h + dyn_tau*rho/rData.DeltaTime + mu*stab_c1/std::pow(h, 2)); + const double crLHS21 = crLHS15*crLHS20; + const double crLHS22 = rho*(DN_v(0,0)*vconv(0,0) + DN_v(0,1)*vconv(0,1) + DN_v(0,2)*vconv(0,2) + DN_v(1,0)*vconv(1,0) + DN_v(1,1)*vconv(1,1) + DN_v(1,2)*vconv(1,2) + DN_v(2,0)*vconv(2,0) + DN_v(2,1)*vconv(2,1) + DN_v(2,2)*vconv(2,2) + DN_v(3,0)*vconv(3,0) + DN_v(3,1)*vconv(3,1) + DN_v(3,2)*vconv(3,2) + DN_v(4,0)*vconv(4,0) + DN_v(4,1)*vconv(4,1) + DN_v(4,2)*vconv(4,2) + DN_v(5,0)*vconv(5,0) + DN_v(5,1)*vconv(5,1) + DN_v(5,2)*vconv(5,2) + DN_v(6,0)*vconv(6,0) + DN_v(6,1)*vconv(6,1) + DN_v(6,2)*vconv(6,2) + DN_v(7,0)*vconv(7,0) + DN_v(7,1)*vconv(7,1) + DN_v(7,2)*vconv(7,2) + DN_v(8,0)*vconv(8,0) + DN_v(8,1)*vconv(8,1) + DN_v(8,2)*vconv(8,2) + DN_v(9,0)*vconv(9,0) + DN_v(9,1)*vconv(9,1) + DN_v(9,2)*vconv(9,2)); + const double crLHS23 = N_v[0]*crLHS22; + const double crLHS24 = crLHS20*crLHS23; + const double crLHS25 = std::pow(N_v[0], 2)*crLHS16 + N_v[0]*crLHS15; + const double crLHS26 = C(0,1)*DN_v(0,1) + C(0,4)*DN_v(0,2) + crLHS1; + const double crLHS27 = C(1,3)*DN_v(0,1); + const double crLHS28 = C(3,3)*DN_v(0,0) + C(3,4)*DN_v(0,2) + crLHS27; + const double crLHS29 = C(3,5)*DN_v(0,0); + const double crLHS30 = C(4,5)*DN_v(0,2); + const double crLHS31 = C(1,5)*DN_v(0,1) + crLHS29 + crLHS30; + const double crLHS32 = DN_v(0,0)*crLHS9; + const double crLHS33 = DN_v(0,1)*crLHS32; + const double crLHS34 = C(3,5)*DDN_v[0](0,0); + const double crLHS35 = C(0,1)*DDN_v[0](0,1) + C(0,4)*DDN_v[0](0,2) + C(1,3)*DDN_v[0](0,1) + C(1,5)*DDN_v[0](0,1) + C(3,3)*DDN_v[0](0,0) + C(3,4)*DDN_v[0](0,2) + C(4,5)*DDN_v[0](0,2) + crLHS11 + crLHS34; + const double crLHS36 = C(0,2)*DN_v(0,2) + C(0,4)*DN_v(0,1) + crLHS3; + const double crLHS37 = C(3,4)*DN_v(0,1); + const double crLHS38 = C(2,3)*DN_v(0,2) + crLHS29 + crLHS37; + const double crLHS39 = C(2,5)*DN_v(0,2); + const double crLHS40 = C(4,5)*DN_v(0,1) + C(5,5)*DN_v(0,0) + crLHS39; + const double crLHS41 = DN_v(0,2)*crLHS32; + const double crLHS42 = C(0,2)*DDN_v[0](0,2) + C(0,4)*DDN_v[0](0,1) + C(2,3)*DDN_v[0](0,2) + C(2,5)*DDN_v[0](0,2) + C(3,4)*DDN_v[0](0,1) + C(4,5)*DDN_v[0](0,1) + C(5,5)*DDN_v[0](0,0) + crLHS13 + crLHS34; + const double crLHS43 = C(0,0)*DN_v(1,0) + C(0,3)*DN_v(1,1) + C(0,5)*DN_v(1,2); + const double crLHS44 = C(0,3)*DN_v(1,0); + const double crLHS45 = C(3,3)*DN_v(1,1) + C(3,5)*DN_v(1,2) + crLHS44; + const double crLHS46 = C(0,5)*DN_v(1,0); + const double crLHS47 = C(3,5)*DN_v(1,1) + C(5,5)*DN_v(1,2) + crLHS46; + const double crLHS48 = DN_v(1,0)*crLHS32; + const double crLHS49 = C(0,3)*DDN_v[1](0,0); + const double crLHS50 = 1.0*DDN_v[1](0,1); + const double crLHS51 = C(0,5)*DDN_v[1](0,0); + const double crLHS52 = 1.0*DDN_v[1](0,2); + const double crLHS53 = rho*(DN_v(1,0)*crLHS5 + DN_v(1,1)*crLHS6 + DN_v(1,2)*crLHS7); + const double crLHS54 = N_v[1]*crLHS16; + const double crLHS55 = -crLHS53 - crLHS54; + const double crLHS56 = C(0,3)*crLHS50 + C(0,5)*crLHS52 + C(3,3)*crLHS50 + C(3,5)*crLHS50 + C(3,5)*crLHS52 + C(5,5)*crLHS52 + DDN_v[1](0,0)*crLHS10 + 1.0*crLHS49 + 1.0*crLHS51 + crLHS55; + const double crLHS57 = N_v[1]*crLHS17; + const double crLHS58 = N_v[0]*crLHS53 + crLHS57; + const double crLHS59 = C(0,1)*DN_v(1,1) + C(0,4)*DN_v(1,2) + crLHS44; + const double crLHS60 = C(1,3)*DN_v(1,1); + const double crLHS61 = C(3,3)*DN_v(1,0) + C(3,4)*DN_v(1,2) + crLHS60; + const double crLHS62 = C(3,5)*DN_v(1,0); + const double crLHS63 = C(4,5)*DN_v(1,2); + const double crLHS64 = C(1,5)*DN_v(1,1) + crLHS62 + crLHS63; + const double crLHS65 = DN_v(1,1)*crLHS32; + const double crLHS66 = C(3,5)*DDN_v[1](0,0); + const double crLHS67 = C(0,1)*DDN_v[1](0,1) + C(0,4)*DDN_v[1](0,2) + C(1,3)*DDN_v[1](0,1) + C(1,5)*DDN_v[1](0,1) + C(3,3)*DDN_v[1](0,0) + C(3,4)*DDN_v[1](0,2) + C(4,5)*DDN_v[1](0,2) + crLHS49 + crLHS66; + const double crLHS68 = C(0,2)*DN_v(1,2) + C(0,4)*DN_v(1,1) + crLHS46; + const double crLHS69 = C(3,4)*DN_v(1,1); + const double crLHS70 = C(2,3)*DN_v(1,2) + crLHS62 + crLHS69; + const double crLHS71 = C(2,5)*DN_v(1,2); + const double crLHS72 = C(4,5)*DN_v(1,1) + C(5,5)*DN_v(1,0) + crLHS71; + const double crLHS73 = DN_v(1,2)*crLHS32; + const double crLHS74 = C(0,2)*DDN_v[1](0,2) + C(0,4)*DDN_v[1](0,1) + C(2,3)*DDN_v[1](0,2) + C(2,5)*DDN_v[1](0,2) + C(3,4)*DDN_v[1](0,1) + C(4,5)*DDN_v[1](0,1) + C(5,5)*DDN_v[1](0,0) + crLHS51 + crLHS66; + const double crLHS75 = C(0,0)*DN_v(2,0) + C(0,3)*DN_v(2,1) + C(0,5)*DN_v(2,2); + const double crLHS76 = C(0,3)*DN_v(2,0); + const double crLHS77 = C(3,3)*DN_v(2,1) + C(3,5)*DN_v(2,2) + crLHS76; + const double crLHS78 = C(0,5)*DN_v(2,0); + const double crLHS79 = C(3,5)*DN_v(2,1) + C(5,5)*DN_v(2,2) + crLHS78; + const double crLHS80 = DN_v(2,0)*crLHS32; + const double crLHS81 = C(0,3)*DDN_v[2](0,0); + const double crLHS82 = 1.0*DDN_v[2](0,1); + const double crLHS83 = C(0,5)*DDN_v[2](0,0); + const double crLHS84 = 1.0*DDN_v[2](0,2); + const double crLHS85 = rho*(DN_v(2,0)*crLHS5 + DN_v(2,1)*crLHS6 + DN_v(2,2)*crLHS7); + const double crLHS86 = N_v[2]*crLHS16; + const double crLHS87 = -crLHS85 - crLHS86; + const double crLHS88 = C(0,3)*crLHS82 + C(0,5)*crLHS84 + C(3,3)*crLHS82 + C(3,5)*crLHS82 + C(3,5)*crLHS84 + C(5,5)*crLHS84 + DDN_v[2](0,0)*crLHS10 + 1.0*crLHS81 + 1.0*crLHS83 + crLHS87; + const double crLHS89 = N_v[2]*crLHS17; + const double crLHS90 = N_v[0]*crLHS85 + crLHS89; + const double crLHS91 = C(0,1)*DN_v(2,1) + C(0,4)*DN_v(2,2) + crLHS76; + const double crLHS92 = C(1,3)*DN_v(2,1); + const double crLHS93 = C(3,3)*DN_v(2,0) + C(3,4)*DN_v(2,2) + crLHS92; + const double crLHS94 = C(3,5)*DN_v(2,0); + const double crLHS95 = C(4,5)*DN_v(2,2); + const double crLHS96 = C(1,5)*DN_v(2,1) + crLHS94 + crLHS95; + const double crLHS97 = DN_v(2,1)*crLHS32; + const double crLHS98 = C(3,5)*DDN_v[2](0,0); + const double crLHS99 = C(0,1)*DDN_v[2](0,1) + C(0,4)*DDN_v[2](0,2) + C(1,3)*DDN_v[2](0,1) + C(1,5)*DDN_v[2](0,1) + C(3,3)*DDN_v[2](0,0) + C(3,4)*DDN_v[2](0,2) + C(4,5)*DDN_v[2](0,2) + crLHS81 + crLHS98; + const double crLHS100 = C(0,2)*DN_v(2,2) + C(0,4)*DN_v(2,1) + crLHS78; + const double crLHS101 = C(3,4)*DN_v(2,1); + const double crLHS102 = C(2,3)*DN_v(2,2) + crLHS101 + crLHS94; + const double crLHS103 = C(2,5)*DN_v(2,2); + const double crLHS104 = C(4,5)*DN_v(2,1) + C(5,5)*DN_v(2,0) + crLHS103; + const double crLHS105 = DN_v(2,2)*crLHS32; + const double crLHS106 = C(0,2)*DDN_v[2](0,2) + C(0,4)*DDN_v[2](0,1) + C(2,3)*DDN_v[2](0,2) + C(2,5)*DDN_v[2](0,2) + C(3,4)*DDN_v[2](0,1) + C(4,5)*DDN_v[2](0,1) + C(5,5)*DDN_v[2](0,0) + crLHS83 + crLHS98; + const double crLHS107 = C(0,0)*DN_v(3,0) + C(0,3)*DN_v(3,1) + C(0,5)*DN_v(3,2); + const double crLHS108 = C(0,3)*DN_v(3,0); + const double crLHS109 = C(3,3)*DN_v(3,1) + C(3,5)*DN_v(3,2) + crLHS108; + const double crLHS110 = C(0,5)*DN_v(3,0); + const double crLHS111 = C(3,5)*DN_v(3,1) + C(5,5)*DN_v(3,2) + crLHS110; + const double crLHS112 = DN_v(3,0)*crLHS32; + const double crLHS113 = C(0,3)*DDN_v[3](0,0); + const double crLHS114 = 1.0*DDN_v[3](0,1); + const double crLHS115 = C(0,5)*DDN_v[3](0,0); + const double crLHS116 = 1.0*DDN_v[3](0,2); + const double crLHS117 = rho*(DN_v(3,0)*crLHS5 + DN_v(3,1)*crLHS6 + DN_v(3,2)*crLHS7); + const double crLHS118 = N_v[3]*crLHS16; + const double crLHS119 = -crLHS117 - crLHS118; + const double crLHS120 = C(0,3)*crLHS114 + C(0,5)*crLHS116 + C(3,3)*crLHS114 + C(3,5)*crLHS114 + C(3,5)*crLHS116 + C(5,5)*crLHS116 + DDN_v[3](0,0)*crLHS10 + 1.0*crLHS113 + 1.0*crLHS115 + crLHS119; + const double crLHS121 = N_v[3]*crLHS17; + const double crLHS122 = N_v[0]*crLHS117 + crLHS121; + const double crLHS123 = C(0,1)*DN_v(3,1) + C(0,4)*DN_v(3,2) + crLHS108; + const double crLHS124 = C(1,3)*DN_v(3,1); + const double crLHS125 = C(3,3)*DN_v(3,0) + C(3,4)*DN_v(3,2) + crLHS124; + const double crLHS126 = C(3,5)*DN_v(3,0); + const double crLHS127 = C(4,5)*DN_v(3,2); + const double crLHS128 = C(1,5)*DN_v(3,1) + crLHS126 + crLHS127; + const double crLHS129 = DN_v(3,1)*crLHS32; + const double crLHS130 = C(3,5)*DDN_v[3](0,0); + const double crLHS131 = C(0,1)*DDN_v[3](0,1) + C(0,4)*DDN_v[3](0,2) + C(1,3)*DDN_v[3](0,1) + C(1,5)*DDN_v[3](0,1) + C(3,3)*DDN_v[3](0,0) + C(3,4)*DDN_v[3](0,2) + C(4,5)*DDN_v[3](0,2) + crLHS113 + crLHS130; + const double crLHS132 = C(0,2)*DN_v(3,2) + C(0,4)*DN_v(3,1) + crLHS110; + const double crLHS133 = C(3,4)*DN_v(3,1); + const double crLHS134 = C(2,3)*DN_v(3,2) + crLHS126 + crLHS133; + const double crLHS135 = C(2,5)*DN_v(3,2); + const double crLHS136 = C(4,5)*DN_v(3,1) + C(5,5)*DN_v(3,0) + crLHS135; + const double crLHS137 = DN_v(3,2)*crLHS32; + const double crLHS138 = C(0,2)*DDN_v[3](0,2) + C(0,4)*DDN_v[3](0,1) + C(2,3)*DDN_v[3](0,2) + C(2,5)*DDN_v[3](0,2) + C(3,4)*DDN_v[3](0,1) + C(4,5)*DDN_v[3](0,1) + C(5,5)*DDN_v[3](0,0) + crLHS115 + crLHS130; + const double crLHS139 = C(0,0)*DN_v(4,0) + C(0,3)*DN_v(4,1) + C(0,5)*DN_v(4,2); + const double crLHS140 = C(0,3)*DN_v(4,0); + const double crLHS141 = C(3,3)*DN_v(4,1) + C(3,5)*DN_v(4,2) + crLHS140; + const double crLHS142 = C(0,5)*DN_v(4,0); + const double crLHS143 = C(3,5)*DN_v(4,1) + C(5,5)*DN_v(4,2) + crLHS142; + const double crLHS144 = DN_v(4,0)*crLHS32; + const double crLHS145 = C(0,3)*DDN_v[4](0,0); + const double crLHS146 = 1.0*DDN_v[4](0,1); + const double crLHS147 = C(0,5)*DDN_v[4](0,0); + const double crLHS148 = 1.0*DDN_v[4](0,2); + const double crLHS149 = rho*(DN_v(4,0)*crLHS5 + DN_v(4,1)*crLHS6 + DN_v(4,2)*crLHS7); + const double crLHS150 = N_v[4]*crLHS16; + const double crLHS151 = -crLHS149 - crLHS150; + const double crLHS152 = C(0,3)*crLHS146 + C(0,5)*crLHS148 + C(3,3)*crLHS146 + C(3,5)*crLHS146 + C(3,5)*crLHS148 + C(5,5)*crLHS148 + DDN_v[4](0,0)*crLHS10 + 1.0*crLHS145 + 1.0*crLHS147 + crLHS151; + const double crLHS153 = N_v[4]*crLHS17; + const double crLHS154 = N_v[0]*crLHS149 + crLHS153; + const double crLHS155 = C(0,1)*DN_v(4,1) + C(0,4)*DN_v(4,2) + crLHS140; + const double crLHS156 = C(1,3)*DN_v(4,1); + const double crLHS157 = C(3,3)*DN_v(4,0) + C(3,4)*DN_v(4,2) + crLHS156; + const double crLHS158 = C(3,5)*DN_v(4,0); + const double crLHS159 = C(4,5)*DN_v(4,2); + const double crLHS160 = C(1,5)*DN_v(4,1) + crLHS158 + crLHS159; + const double crLHS161 = DN_v(4,1)*crLHS32; + const double crLHS162 = C(3,5)*DDN_v[4](0,0); + const double crLHS163 = C(0,1)*DDN_v[4](0,1) + C(0,4)*DDN_v[4](0,2) + C(1,3)*DDN_v[4](0,1) + C(1,5)*DDN_v[4](0,1) + C(3,3)*DDN_v[4](0,0) + C(3,4)*DDN_v[4](0,2) + C(4,5)*DDN_v[4](0,2) + crLHS145 + crLHS162; + const double crLHS164 = C(0,2)*DN_v(4,2) + C(0,4)*DN_v(4,1) + crLHS142; + const double crLHS165 = C(3,4)*DN_v(4,1); + const double crLHS166 = C(2,3)*DN_v(4,2) + crLHS158 + crLHS165; + const double crLHS167 = C(2,5)*DN_v(4,2); + const double crLHS168 = C(4,5)*DN_v(4,1) + C(5,5)*DN_v(4,0) + crLHS167; + const double crLHS169 = DN_v(4,2)*crLHS32; + const double crLHS170 = C(0,2)*DDN_v[4](0,2) + C(0,4)*DDN_v[4](0,1) + C(2,3)*DDN_v[4](0,2) + C(2,5)*DDN_v[4](0,2) + C(3,4)*DDN_v[4](0,1) + C(4,5)*DDN_v[4](0,1) + C(5,5)*DDN_v[4](0,0) + crLHS147 + crLHS162; + const double crLHS171 = C(0,0)*DN_v(5,0) + C(0,3)*DN_v(5,1) + C(0,5)*DN_v(5,2); + const double crLHS172 = C(0,3)*DN_v(5,0); + const double crLHS173 = C(3,3)*DN_v(5,1) + C(3,5)*DN_v(5,2) + crLHS172; + const double crLHS174 = C(0,5)*DN_v(5,0); + const double crLHS175 = C(3,5)*DN_v(5,1) + C(5,5)*DN_v(5,2) + crLHS174; + const double crLHS176 = DN_v(5,0)*crLHS32; + const double crLHS177 = C(0,3)*DDN_v[5](0,0); + const double crLHS178 = 1.0*DDN_v[5](0,1); + const double crLHS179 = C(0,5)*DDN_v[5](0,0); + const double crLHS180 = 1.0*DDN_v[5](0,2); + const double crLHS181 = rho*(DN_v(5,0)*crLHS5 + DN_v(5,1)*crLHS6 + DN_v(5,2)*crLHS7); + const double crLHS182 = N_v[5]*crLHS16; + const double crLHS183 = -crLHS181 - crLHS182; + const double crLHS184 = C(0,3)*crLHS178 + C(0,5)*crLHS180 + C(3,3)*crLHS178 + C(3,5)*crLHS178 + C(3,5)*crLHS180 + C(5,5)*crLHS180 + DDN_v[5](0,0)*crLHS10 + 1.0*crLHS177 + 1.0*crLHS179 + crLHS183; + const double crLHS185 = N_v[5]*crLHS17; + const double crLHS186 = N_v[0]*crLHS181 + crLHS185; + const double crLHS187 = C(0,1)*DN_v(5,1) + C(0,4)*DN_v(5,2) + crLHS172; + const double crLHS188 = C(1,3)*DN_v(5,1); + const double crLHS189 = C(3,3)*DN_v(5,0) + C(3,4)*DN_v(5,2) + crLHS188; + const double crLHS190 = C(3,5)*DN_v(5,0); + const double crLHS191 = C(4,5)*DN_v(5,2); + const double crLHS192 = C(1,5)*DN_v(5,1) + crLHS190 + crLHS191; + const double crLHS193 = DN_v(5,1)*crLHS32; + const double crLHS194 = C(3,5)*DDN_v[5](0,0); + const double crLHS195 = C(0,1)*DDN_v[5](0,1) + C(0,4)*DDN_v[5](0,2) + C(1,3)*DDN_v[5](0,1) + C(1,5)*DDN_v[5](0,1) + C(3,3)*DDN_v[5](0,0) + C(3,4)*DDN_v[5](0,2) + C(4,5)*DDN_v[5](0,2) + crLHS177 + crLHS194; + const double crLHS196 = C(0,2)*DN_v(5,2) + C(0,4)*DN_v(5,1) + crLHS174; + const double crLHS197 = C(3,4)*DN_v(5,1); + const double crLHS198 = C(2,3)*DN_v(5,2) + crLHS190 + crLHS197; + const double crLHS199 = C(2,5)*DN_v(5,2); + const double crLHS200 = C(4,5)*DN_v(5,1) + C(5,5)*DN_v(5,0) + crLHS199; + const double crLHS201 = DN_v(5,2)*crLHS32; + const double crLHS202 = C(0,2)*DDN_v[5](0,2) + C(0,4)*DDN_v[5](0,1) + C(2,3)*DDN_v[5](0,2) + C(2,5)*DDN_v[5](0,2) + C(3,4)*DDN_v[5](0,1) + C(4,5)*DDN_v[5](0,1) + C(5,5)*DDN_v[5](0,0) + crLHS179 + crLHS194; + const double crLHS203 = C(0,0)*DN_v(6,0) + C(0,3)*DN_v(6,1) + C(0,5)*DN_v(6,2); + const double crLHS204 = C(0,3)*DN_v(6,0); + const double crLHS205 = C(3,3)*DN_v(6,1) + C(3,5)*DN_v(6,2) + crLHS204; + const double crLHS206 = C(0,5)*DN_v(6,0); + const double crLHS207 = C(3,5)*DN_v(6,1) + C(5,5)*DN_v(6,2) + crLHS206; + const double crLHS208 = DN_v(6,0)*crLHS32; + const double crLHS209 = C(0,3)*DDN_v[6](0,0); + const double crLHS210 = 1.0*DDN_v[6](0,1); + const double crLHS211 = C(0,5)*DDN_v[6](0,0); + const double crLHS212 = 1.0*DDN_v[6](0,2); + const double crLHS213 = rho*(DN_v(6,0)*crLHS5 + DN_v(6,1)*crLHS6 + DN_v(6,2)*crLHS7); + const double crLHS214 = N_v[6]*crLHS16; + const double crLHS215 = -crLHS213 - crLHS214; + const double crLHS216 = C(0,3)*crLHS210 + C(0,5)*crLHS212 + C(3,3)*crLHS210 + C(3,5)*crLHS210 + C(3,5)*crLHS212 + C(5,5)*crLHS212 + DDN_v[6](0,0)*crLHS10 + 1.0*crLHS209 + 1.0*crLHS211 + crLHS215; + const double crLHS217 = N_v[6]*crLHS17; + const double crLHS218 = N_v[0]*crLHS213 + crLHS217; + const double crLHS219 = C(0,1)*DN_v(6,1) + C(0,4)*DN_v(6,2) + crLHS204; + const double crLHS220 = C(1,3)*DN_v(6,1); + const double crLHS221 = C(3,3)*DN_v(6,0) + C(3,4)*DN_v(6,2) + crLHS220; + const double crLHS222 = C(3,5)*DN_v(6,0); + const double crLHS223 = C(4,5)*DN_v(6,2); + const double crLHS224 = C(1,5)*DN_v(6,1) + crLHS222 + crLHS223; + const double crLHS225 = DN_v(6,1)*crLHS32; + const double crLHS226 = C(3,5)*DDN_v[6](0,0); + const double crLHS227 = C(0,1)*DDN_v[6](0,1) + C(0,4)*DDN_v[6](0,2) + C(1,3)*DDN_v[6](0,1) + C(1,5)*DDN_v[6](0,1) + C(3,3)*DDN_v[6](0,0) + C(3,4)*DDN_v[6](0,2) + C(4,5)*DDN_v[6](0,2) + crLHS209 + crLHS226; + const double crLHS228 = C(0,2)*DN_v(6,2) + C(0,4)*DN_v(6,1) + crLHS206; + const double crLHS229 = C(3,4)*DN_v(6,1); + const double crLHS230 = C(2,3)*DN_v(6,2) + crLHS222 + crLHS229; + const double crLHS231 = C(2,5)*DN_v(6,2); + const double crLHS232 = C(4,5)*DN_v(6,1) + C(5,5)*DN_v(6,0) + crLHS231; + const double crLHS233 = DN_v(6,2)*crLHS32; + const double crLHS234 = C(0,2)*DDN_v[6](0,2) + C(0,4)*DDN_v[6](0,1) + C(2,3)*DDN_v[6](0,2) + C(2,5)*DDN_v[6](0,2) + C(3,4)*DDN_v[6](0,1) + C(4,5)*DDN_v[6](0,1) + C(5,5)*DDN_v[6](0,0) + crLHS211 + crLHS226; + const double crLHS235 = C(0,0)*DN_v(7,0) + C(0,3)*DN_v(7,1) + C(0,5)*DN_v(7,2); + const double crLHS236 = C(0,3)*DN_v(7,0); + const double crLHS237 = C(3,3)*DN_v(7,1) + C(3,5)*DN_v(7,2) + crLHS236; + const double crLHS238 = C(0,5)*DN_v(7,0); + const double crLHS239 = C(3,5)*DN_v(7,1) + C(5,5)*DN_v(7,2) + crLHS238; + const double crLHS240 = DN_v(7,0)*crLHS32; + const double crLHS241 = C(0,3)*DDN_v[7](0,0); + const double crLHS242 = 1.0*DDN_v[7](0,1); + const double crLHS243 = C(0,5)*DDN_v[7](0,0); + const double crLHS244 = 1.0*DDN_v[7](0,2); + const double crLHS245 = rho*(DN_v(7,0)*crLHS5 + DN_v(7,1)*crLHS6 + DN_v(7,2)*crLHS7); + const double crLHS246 = N_v[7]*crLHS16; + const double crLHS247 = -crLHS245 - crLHS246; + const double crLHS248 = C(0,3)*crLHS242 + C(0,5)*crLHS244 + C(3,3)*crLHS242 + C(3,5)*crLHS242 + C(3,5)*crLHS244 + C(5,5)*crLHS244 + DDN_v[7](0,0)*crLHS10 + 1.0*crLHS241 + 1.0*crLHS243 + crLHS247; + const double crLHS249 = N_v[7]*crLHS17; + const double crLHS250 = N_v[0]*crLHS245 + crLHS249; + const double crLHS251 = C(0,1)*DN_v(7,1) + C(0,4)*DN_v(7,2) + crLHS236; + const double crLHS252 = C(1,3)*DN_v(7,1); + const double crLHS253 = C(3,3)*DN_v(7,0) + C(3,4)*DN_v(7,2) + crLHS252; + const double crLHS254 = C(3,5)*DN_v(7,0); + const double crLHS255 = C(4,5)*DN_v(7,2); + const double crLHS256 = C(1,5)*DN_v(7,1) + crLHS254 + crLHS255; + const double crLHS257 = DN_v(7,1)*crLHS32; + const double crLHS258 = C(3,5)*DDN_v[7](0,0); + const double crLHS259 = C(0,1)*DDN_v[7](0,1) + C(0,4)*DDN_v[7](0,2) + C(1,3)*DDN_v[7](0,1) + C(1,5)*DDN_v[7](0,1) + C(3,3)*DDN_v[7](0,0) + C(3,4)*DDN_v[7](0,2) + C(4,5)*DDN_v[7](0,2) + crLHS241 + crLHS258; + const double crLHS260 = C(0,2)*DN_v(7,2) + C(0,4)*DN_v(7,1) + crLHS238; + const double crLHS261 = C(3,4)*DN_v(7,1); + const double crLHS262 = C(2,3)*DN_v(7,2) + crLHS254 + crLHS261; + const double crLHS263 = C(2,5)*DN_v(7,2); + const double crLHS264 = C(4,5)*DN_v(7,1) + C(5,5)*DN_v(7,0) + crLHS263; + const double crLHS265 = DN_v(7,2)*crLHS32; + const double crLHS266 = C(0,2)*DDN_v[7](0,2) + C(0,4)*DDN_v[7](0,1) + C(2,3)*DDN_v[7](0,2) + C(2,5)*DDN_v[7](0,2) + C(3,4)*DDN_v[7](0,1) + C(4,5)*DDN_v[7](0,1) + C(5,5)*DDN_v[7](0,0) + crLHS243 + crLHS258; + const double crLHS267 = C(0,0)*DN_v(8,0) + C(0,3)*DN_v(8,1) + C(0,5)*DN_v(8,2); + const double crLHS268 = C(0,3)*DN_v(8,0); + const double crLHS269 = C(3,3)*DN_v(8,1) + C(3,5)*DN_v(8,2) + crLHS268; + const double crLHS270 = C(0,5)*DN_v(8,0); + const double crLHS271 = C(3,5)*DN_v(8,1) + C(5,5)*DN_v(8,2) + crLHS270; + const double crLHS272 = DN_v(8,0)*crLHS32; + const double crLHS273 = C(0,3)*DDN_v[8](0,0); + const double crLHS274 = 1.0*DDN_v[8](0,1); + const double crLHS275 = C(0,5)*DDN_v[8](0,0); + const double crLHS276 = 1.0*DDN_v[8](0,2); + const double crLHS277 = rho*(DN_v(8,0)*crLHS5 + DN_v(8,1)*crLHS6 + DN_v(8,2)*crLHS7); + const double crLHS278 = N_v[8]*crLHS16; + const double crLHS279 = -crLHS277 - crLHS278; + const double crLHS280 = C(0,3)*crLHS274 + C(0,5)*crLHS276 + C(3,3)*crLHS274 + C(3,5)*crLHS274 + C(3,5)*crLHS276 + C(5,5)*crLHS276 + DDN_v[8](0,0)*crLHS10 + 1.0*crLHS273 + 1.0*crLHS275 + crLHS279; + const double crLHS281 = N_v[8]*crLHS17; + const double crLHS282 = N_v[0]*crLHS277 + crLHS281; + const double crLHS283 = C(0,1)*DN_v(8,1) + C(0,4)*DN_v(8,2) + crLHS268; + const double crLHS284 = C(1,3)*DN_v(8,1); + const double crLHS285 = C(3,3)*DN_v(8,0) + C(3,4)*DN_v(8,2) + crLHS284; + const double crLHS286 = C(3,5)*DN_v(8,0); + const double crLHS287 = C(4,5)*DN_v(8,2); + const double crLHS288 = C(1,5)*DN_v(8,1) + crLHS286 + crLHS287; + const double crLHS289 = DN_v(8,1)*crLHS32; + const double crLHS290 = C(3,5)*DDN_v[8](0,0); + const double crLHS291 = C(0,1)*DDN_v[8](0,1) + C(0,4)*DDN_v[8](0,2) + C(1,3)*DDN_v[8](0,1) + C(1,5)*DDN_v[8](0,1) + C(3,3)*DDN_v[8](0,0) + C(3,4)*DDN_v[8](0,2) + C(4,5)*DDN_v[8](0,2) + crLHS273 + crLHS290; + const double crLHS292 = C(0,2)*DN_v(8,2) + C(0,4)*DN_v(8,1) + crLHS270; + const double crLHS293 = C(3,4)*DN_v(8,1); + const double crLHS294 = C(2,3)*DN_v(8,2) + crLHS286 + crLHS293; + const double crLHS295 = C(2,5)*DN_v(8,2); + const double crLHS296 = C(4,5)*DN_v(8,1) + C(5,5)*DN_v(8,0) + crLHS295; + const double crLHS297 = DN_v(8,2)*crLHS32; + const double crLHS298 = C(0,2)*DDN_v[8](0,2) + C(0,4)*DDN_v[8](0,1) + C(2,3)*DDN_v[8](0,2) + C(2,5)*DDN_v[8](0,2) + C(3,4)*DDN_v[8](0,1) + C(4,5)*DDN_v[8](0,1) + C(5,5)*DDN_v[8](0,0) + crLHS275 + crLHS290; + const double crLHS299 = C(0,0)*DN_v(9,0) + C(0,3)*DN_v(9,1) + C(0,5)*DN_v(9,2); + const double crLHS300 = C(0,3)*DN_v(9,0); + const double crLHS301 = C(3,3)*DN_v(9,1) + C(3,5)*DN_v(9,2) + crLHS300; + const double crLHS302 = C(0,5)*DN_v(9,0); + const double crLHS303 = C(3,5)*DN_v(9,1) + C(5,5)*DN_v(9,2) + crLHS302; + const double crLHS304 = DN_v(9,0)*crLHS32; + const double crLHS305 = C(0,3)*DDN_v[9](0,0); + const double crLHS306 = 1.0*DDN_v[9](0,1); + const double crLHS307 = C(0,5)*DDN_v[9](0,0); + const double crLHS308 = 1.0*DDN_v[9](0,2); + const double crLHS309 = rho*(DN_v(9,0)*crLHS5 + DN_v(9,1)*crLHS6 + DN_v(9,2)*crLHS7); + const double crLHS310 = -N_v[9]*crLHS16 - crLHS309; + const double crLHS311 = C(0,3)*crLHS306 + C(0,5)*crLHS308 + C(3,3)*crLHS306 + C(3,5)*crLHS306 + C(3,5)*crLHS308 + C(5,5)*crLHS308 + DDN_v[9](0,0)*crLHS10 + 1.0*crLHS305 + 1.0*crLHS307 + crLHS310; + const double crLHS312 = N_v[9]*crLHS17; + const double crLHS313 = N_v[0]*crLHS309 + crLHS312; + const double crLHS314 = C(0,1)*DN_v(9,1) + C(0,4)*DN_v(9,2) + crLHS300; + const double crLHS315 = C(1,3)*DN_v(9,1); + const double crLHS316 = C(3,3)*DN_v(9,0) + C(3,4)*DN_v(9,2) + crLHS315; + const double crLHS317 = C(3,5)*DN_v(9,0); + const double crLHS318 = C(4,5)*DN_v(9,2); + const double crLHS319 = C(1,5)*DN_v(9,1) + crLHS317 + crLHS318; + const double crLHS320 = DN_v(9,1)*crLHS32; + const double crLHS321 = C(3,5)*DDN_v[9](0,0); + const double crLHS322 = C(0,1)*DDN_v[9](0,1) + C(0,4)*DDN_v[9](0,2) + C(1,3)*DDN_v[9](0,1) + C(1,5)*DDN_v[9](0,1) + C(3,3)*DDN_v[9](0,0) + C(3,4)*DDN_v[9](0,2) + C(4,5)*DDN_v[9](0,2) + crLHS305 + crLHS321; + const double crLHS323 = C(0,2)*DN_v(9,2) + C(0,4)*DN_v(9,1) + crLHS302; + const double crLHS324 = C(3,4)*DN_v(9,1); + const double crLHS325 = C(2,3)*DN_v(9,2) + crLHS317 + crLHS324; + const double crLHS326 = C(2,5)*DN_v(9,2); + const double crLHS327 = C(4,5)*DN_v(9,1) + C(5,5)*DN_v(9,0) + crLHS326; + const double crLHS328 = DN_v(9,2)*crLHS32; + const double crLHS329 = C(0,2)*DDN_v[9](0,2) + C(0,4)*DDN_v[9](0,1) + C(2,3)*DDN_v[9](0,2) + C(2,5)*DDN_v[9](0,2) + C(3,4)*DDN_v[9](0,1) + C(4,5)*DDN_v[9](0,1) + C(5,5)*DDN_v[9](0,0) + crLHS307 + crLHS321; + const double crLHS330 = -DN_v(0,0)*N_p[0]; + const double crLHS331 = DN_p(0,0)*crLHS20; + const double crLHS332 = -DN_v(0,0)*N_p[1]; + const double crLHS333 = DN_p(1,0)*crLHS20; + const double crLHS334 = -DN_v(0,0)*N_p[2]; + const double crLHS335 = DN_p(2,0)*crLHS20; + const double crLHS336 = -DN_v(0,0)*N_p[3]; + const double crLHS337 = DN_p(3,0)*crLHS20; + const double crLHS338 = C(0,1)*DN_v(0,0) + C(1,5)*DN_v(0,2) + crLHS27; + const double crLHS339 = C(0,4)*DN_v(0,0) + crLHS30 + crLHS37; + const double crLHS340 = C(1,3)*DDN_v[0](1,1); + const double crLHS341 = C(3,4)*DDN_v[0](1,1); + const double crLHS342 = C(0,1)*DDN_v[0](1,0) + C(0,3)*DDN_v[0](1,0) + C(0,4)*DDN_v[0](1,0) + C(1,5)*DDN_v[0](1,2) + C(3,3)*DDN_v[0](1,1) + C(3,5)*DDN_v[0](1,2) + C(4,5)*DDN_v[0](1,2) + crLHS340 + crLHS341; + const double crLHS343 = C(1,1)*DN_v(0,1) + C(1,3)*DN_v(0,0) + C(1,4)*DN_v(0,2); + const double crLHS344 = C(1,4)*DN_v(0,1); + const double crLHS345 = C(3,4)*DN_v(0,0) + C(4,4)*DN_v(0,2) + crLHS344; + const double crLHS346 = 1.0*C(1,1); + const double crLHS347 = 1.0*DDN_v[0](1,0); + const double crLHS348 = C(1,4)*DDN_v[0](1,1); + const double crLHS349 = 1.0*DDN_v[0](1,2); + const double crLHS350 = C(1,3)*crLHS347 + C(1,4)*crLHS349 + C(3,3)*crLHS347 + C(3,4)*crLHS347 + C(3,4)*crLHS349 + C(4,4)*crLHS349 + DDN_v[0](1,1)*crLHS346 + crLHS18 + 1.0*crLHS340 + 1.0*crLHS348; + const double crLHS351 = C(1,2)*DN_v(0,2) + C(1,5)*DN_v(0,0) + crLHS344; + const double crLHS352 = C(2,4)*DN_v(0,2); + const double crLHS353 = C(4,4)*DN_v(0,1) + C(4,5)*DN_v(0,0) + crLHS352; + const double crLHS354 = DN_v(0,1)*crLHS9; + const double crLHS355 = DN_v(0,2)*crLHS354; + const double crLHS356 = C(1,2)*DDN_v[0](1,2) + C(1,5)*DDN_v[0](1,0) + C(2,3)*DDN_v[0](1,2) + C(2,4)*DDN_v[0](1,2) + C(3,5)*DDN_v[0](1,0) + C(4,4)*DDN_v[0](1,1) + C(4,5)*DDN_v[0](1,0) + crLHS341 + crLHS348; + const double crLHS357 = C(0,1)*DN_v(1,0) + C(1,5)*DN_v(1,2) + crLHS60; + const double crLHS358 = C(0,4)*DN_v(1,0) + crLHS63 + crLHS69; + const double crLHS359 = DN_v(1,0)*crLHS354; + const double crLHS360 = C(1,3)*DDN_v[1](1,1); + const double crLHS361 = C(3,4)*DDN_v[1](1,1); + const double crLHS362 = C(0,1)*DDN_v[1](1,0) + C(0,3)*DDN_v[1](1,0) + C(0,4)*DDN_v[1](1,0) + C(1,5)*DDN_v[1](1,2) + C(3,3)*DDN_v[1](1,1) + C(3,5)*DDN_v[1](1,2) + C(4,5)*DDN_v[1](1,2) + crLHS360 + crLHS361; + const double crLHS363 = C(1,1)*DN_v(1,1) + C(1,3)*DN_v(1,0) + C(1,4)*DN_v(1,2); + const double crLHS364 = C(1,4)*DN_v(1,1); + const double crLHS365 = C(3,4)*DN_v(1,0) + C(4,4)*DN_v(1,2) + crLHS364; + const double crLHS366 = DN_v(1,1)*crLHS354; + const double crLHS367 = 1.0*DDN_v[1](1,0); + const double crLHS368 = C(1,4)*DDN_v[1](1,1); + const double crLHS369 = 1.0*DDN_v[1](1,2); + const double crLHS370 = C(1,3)*crLHS367 + C(1,4)*crLHS369 + C(3,3)*crLHS367 + C(3,4)*crLHS367 + C(3,4)*crLHS369 + C(4,4)*crLHS369 + DDN_v[1](1,1)*crLHS346 + 1.0*crLHS360 + 1.0*crLHS368 + crLHS55; + const double crLHS371 = C(1,2)*DN_v(1,2) + C(1,5)*DN_v(1,0) + crLHS364; + const double crLHS372 = C(2,4)*DN_v(1,2); + const double crLHS373 = C(4,4)*DN_v(1,1) + C(4,5)*DN_v(1,0) + crLHS372; + const double crLHS374 = DN_v(1,2)*crLHS354; + const double crLHS375 = C(1,2)*DDN_v[1](1,2) + C(1,5)*DDN_v[1](1,0) + C(2,3)*DDN_v[1](1,2) + C(2,4)*DDN_v[1](1,2) + C(3,5)*DDN_v[1](1,0) + C(4,4)*DDN_v[1](1,1) + C(4,5)*DDN_v[1](1,0) + crLHS361 + crLHS368; + const double crLHS376 = C(0,1)*DN_v(2,0) + C(1,5)*DN_v(2,2) + crLHS92; + const double crLHS377 = C(0,4)*DN_v(2,0) + crLHS101 + crLHS95; + const double crLHS378 = DN_v(2,0)*crLHS354; + const double crLHS379 = C(1,3)*DDN_v[2](1,1); + const double crLHS380 = C(3,4)*DDN_v[2](1,1); + const double crLHS381 = C(0,1)*DDN_v[2](1,0) + C(0,3)*DDN_v[2](1,0) + C(0,4)*DDN_v[2](1,0) + C(1,5)*DDN_v[2](1,2) + C(3,3)*DDN_v[2](1,1) + C(3,5)*DDN_v[2](1,2) + C(4,5)*DDN_v[2](1,2) + crLHS379 + crLHS380; + const double crLHS382 = C(1,1)*DN_v(2,1) + C(1,3)*DN_v(2,0) + C(1,4)*DN_v(2,2); + const double crLHS383 = C(1,4)*DN_v(2,1); + const double crLHS384 = C(3,4)*DN_v(2,0) + C(4,4)*DN_v(2,2) + crLHS383; + const double crLHS385 = DN_v(2,1)*crLHS354; + const double crLHS386 = 1.0*DDN_v[2](1,0); + const double crLHS387 = C(1,4)*DDN_v[2](1,1); + const double crLHS388 = 1.0*DDN_v[2](1,2); + const double crLHS389 = C(1,3)*crLHS386 + C(1,4)*crLHS388 + C(3,3)*crLHS386 + C(3,4)*crLHS386 + C(3,4)*crLHS388 + C(4,4)*crLHS388 + DDN_v[2](1,1)*crLHS346 + 1.0*crLHS379 + 1.0*crLHS387 + crLHS87; + const double crLHS390 = C(1,2)*DN_v(2,2) + C(1,5)*DN_v(2,0) + crLHS383; + const double crLHS391 = C(2,4)*DN_v(2,2); + const double crLHS392 = C(4,4)*DN_v(2,1) + C(4,5)*DN_v(2,0) + crLHS391; + const double crLHS393 = DN_v(2,2)*crLHS354; + const double crLHS394 = C(1,2)*DDN_v[2](1,2) + C(1,5)*DDN_v[2](1,0) + C(2,3)*DDN_v[2](1,2) + C(2,4)*DDN_v[2](1,2) + C(3,5)*DDN_v[2](1,0) + C(4,4)*DDN_v[2](1,1) + C(4,5)*DDN_v[2](1,0) + crLHS380 + crLHS387; + const double crLHS395 = C(0,1)*DN_v(3,0) + C(1,5)*DN_v(3,2) + crLHS124; + const double crLHS396 = C(0,4)*DN_v(3,0) + crLHS127 + crLHS133; + const double crLHS397 = DN_v(3,0)*crLHS354; + const double crLHS398 = C(1,3)*DDN_v[3](1,1); + const double crLHS399 = C(3,4)*DDN_v[3](1,1); + const double crLHS400 = C(0,1)*DDN_v[3](1,0) + C(0,3)*DDN_v[3](1,0) + C(0,4)*DDN_v[3](1,0) + C(1,5)*DDN_v[3](1,2) + C(3,3)*DDN_v[3](1,1) + C(3,5)*DDN_v[3](1,2) + C(4,5)*DDN_v[3](1,2) + crLHS398 + crLHS399; + const double crLHS401 = C(1,1)*DN_v(3,1) + C(1,3)*DN_v(3,0) + C(1,4)*DN_v(3,2); + const double crLHS402 = C(1,4)*DN_v(3,1); + const double crLHS403 = C(3,4)*DN_v(3,0) + C(4,4)*DN_v(3,2) + crLHS402; + const double crLHS404 = DN_v(3,1)*crLHS354; + const double crLHS405 = 1.0*DDN_v[3](1,0); + const double crLHS406 = C(1,4)*DDN_v[3](1,1); + const double crLHS407 = 1.0*DDN_v[3](1,2); + const double crLHS408 = C(1,3)*crLHS405 + C(1,4)*crLHS407 + C(3,3)*crLHS405 + C(3,4)*crLHS405 + C(3,4)*crLHS407 + C(4,4)*crLHS407 + DDN_v[3](1,1)*crLHS346 + crLHS119 + 1.0*crLHS398 + 1.0*crLHS406; + const double crLHS409 = C(1,2)*DN_v(3,2) + C(1,5)*DN_v(3,0) + crLHS402; + const double crLHS410 = C(2,4)*DN_v(3,2); + const double crLHS411 = C(4,4)*DN_v(3,1) + C(4,5)*DN_v(3,0) + crLHS410; + const double crLHS412 = DN_v(3,2)*crLHS354; + const double crLHS413 = C(1,2)*DDN_v[3](1,2) + C(1,5)*DDN_v[3](1,0) + C(2,3)*DDN_v[3](1,2) + C(2,4)*DDN_v[3](1,2) + C(3,5)*DDN_v[3](1,0) + C(4,4)*DDN_v[3](1,1) + C(4,5)*DDN_v[3](1,0) + crLHS399 + crLHS406; + const double crLHS414 = C(0,1)*DN_v(4,0) + C(1,5)*DN_v(4,2) + crLHS156; + const double crLHS415 = C(0,4)*DN_v(4,0) + crLHS159 + crLHS165; + const double crLHS416 = DN_v(4,0)*crLHS354; + const double crLHS417 = C(1,3)*DDN_v[4](1,1); + const double crLHS418 = C(3,4)*DDN_v[4](1,1); + const double crLHS419 = C(0,1)*DDN_v[4](1,0) + C(0,3)*DDN_v[4](1,0) + C(0,4)*DDN_v[4](1,0) + C(1,5)*DDN_v[4](1,2) + C(3,3)*DDN_v[4](1,1) + C(3,5)*DDN_v[4](1,2) + C(4,5)*DDN_v[4](1,2) + crLHS417 + crLHS418; + const double crLHS420 = C(1,1)*DN_v(4,1) + C(1,3)*DN_v(4,0) + C(1,4)*DN_v(4,2); + const double crLHS421 = C(1,4)*DN_v(4,1); + const double crLHS422 = C(3,4)*DN_v(4,0) + C(4,4)*DN_v(4,2) + crLHS421; + const double crLHS423 = DN_v(4,1)*crLHS354; + const double crLHS424 = 1.0*DDN_v[4](1,0); + const double crLHS425 = C(1,4)*DDN_v[4](1,1); + const double crLHS426 = 1.0*DDN_v[4](1,2); + const double crLHS427 = C(1,3)*crLHS424 + C(1,4)*crLHS426 + C(3,3)*crLHS424 + C(3,4)*crLHS424 + C(3,4)*crLHS426 + C(4,4)*crLHS426 + DDN_v[4](1,1)*crLHS346 + crLHS151 + 1.0*crLHS417 + 1.0*crLHS425; + const double crLHS428 = C(1,2)*DN_v(4,2) + C(1,5)*DN_v(4,0) + crLHS421; + const double crLHS429 = C(2,4)*DN_v(4,2); + const double crLHS430 = C(4,4)*DN_v(4,1) + C(4,5)*DN_v(4,0) + crLHS429; + const double crLHS431 = DN_v(4,2)*crLHS354; + const double crLHS432 = C(1,2)*DDN_v[4](1,2) + C(1,5)*DDN_v[4](1,0) + C(2,3)*DDN_v[4](1,2) + C(2,4)*DDN_v[4](1,2) + C(3,5)*DDN_v[4](1,0) + C(4,4)*DDN_v[4](1,1) + C(4,5)*DDN_v[4](1,0) + crLHS418 + crLHS425; + const double crLHS433 = C(0,1)*DN_v(5,0) + C(1,5)*DN_v(5,2) + crLHS188; + const double crLHS434 = C(0,4)*DN_v(5,0) + crLHS191 + crLHS197; + const double crLHS435 = DN_v(5,0)*crLHS354; + const double crLHS436 = C(1,3)*DDN_v[5](1,1); + const double crLHS437 = C(3,4)*DDN_v[5](1,1); + const double crLHS438 = C(0,1)*DDN_v[5](1,0) + C(0,3)*DDN_v[5](1,0) + C(0,4)*DDN_v[5](1,0) + C(1,5)*DDN_v[5](1,2) + C(3,3)*DDN_v[5](1,1) + C(3,5)*DDN_v[5](1,2) + C(4,5)*DDN_v[5](1,2) + crLHS436 + crLHS437; + const double crLHS439 = C(1,1)*DN_v(5,1) + C(1,3)*DN_v(5,0) + C(1,4)*DN_v(5,2); + const double crLHS440 = C(1,4)*DN_v(5,1); + const double crLHS441 = C(3,4)*DN_v(5,0) + C(4,4)*DN_v(5,2) + crLHS440; + const double crLHS442 = DN_v(5,1)*crLHS354; + const double crLHS443 = 1.0*DDN_v[5](1,0); + const double crLHS444 = C(1,4)*DDN_v[5](1,1); + const double crLHS445 = 1.0*DDN_v[5](1,2); + const double crLHS446 = C(1,3)*crLHS443 + C(1,4)*crLHS445 + C(3,3)*crLHS443 + C(3,4)*crLHS443 + C(3,4)*crLHS445 + C(4,4)*crLHS445 + DDN_v[5](1,1)*crLHS346 + crLHS183 + 1.0*crLHS436 + 1.0*crLHS444; + const double crLHS447 = C(1,2)*DN_v(5,2) + C(1,5)*DN_v(5,0) + crLHS440; + const double crLHS448 = C(2,4)*DN_v(5,2); + const double crLHS449 = C(4,4)*DN_v(5,1) + C(4,5)*DN_v(5,0) + crLHS448; + const double crLHS450 = DN_v(5,2)*crLHS354; + const double crLHS451 = C(1,2)*DDN_v[5](1,2) + C(1,5)*DDN_v[5](1,0) + C(2,3)*DDN_v[5](1,2) + C(2,4)*DDN_v[5](1,2) + C(3,5)*DDN_v[5](1,0) + C(4,4)*DDN_v[5](1,1) + C(4,5)*DDN_v[5](1,0) + crLHS437 + crLHS444; + const double crLHS452 = C(0,1)*DN_v(6,0) + C(1,5)*DN_v(6,2) + crLHS220; + const double crLHS453 = C(0,4)*DN_v(6,0) + crLHS223 + crLHS229; + const double crLHS454 = DN_v(6,0)*crLHS354; + const double crLHS455 = C(1,3)*DDN_v[6](1,1); + const double crLHS456 = C(3,4)*DDN_v[6](1,1); + const double crLHS457 = C(0,1)*DDN_v[6](1,0) + C(0,3)*DDN_v[6](1,0) + C(0,4)*DDN_v[6](1,0) + C(1,5)*DDN_v[6](1,2) + C(3,3)*DDN_v[6](1,1) + C(3,5)*DDN_v[6](1,2) + C(4,5)*DDN_v[6](1,2) + crLHS455 + crLHS456; + const double crLHS458 = C(1,1)*DN_v(6,1) + C(1,3)*DN_v(6,0) + C(1,4)*DN_v(6,2); + const double crLHS459 = C(1,4)*DN_v(6,1); + const double crLHS460 = C(3,4)*DN_v(6,0) + C(4,4)*DN_v(6,2) + crLHS459; + const double crLHS461 = DN_v(6,1)*crLHS354; + const double crLHS462 = 1.0*DDN_v[6](1,0); + const double crLHS463 = C(1,4)*DDN_v[6](1,1); + const double crLHS464 = 1.0*DDN_v[6](1,2); + const double crLHS465 = C(1,3)*crLHS462 + C(1,4)*crLHS464 + C(3,3)*crLHS462 + C(3,4)*crLHS462 + C(3,4)*crLHS464 + C(4,4)*crLHS464 + DDN_v[6](1,1)*crLHS346 + crLHS215 + 1.0*crLHS455 + 1.0*crLHS463; + const double crLHS466 = C(1,2)*DN_v(6,2) + C(1,5)*DN_v(6,0) + crLHS459; + const double crLHS467 = C(2,4)*DN_v(6,2); + const double crLHS468 = C(4,4)*DN_v(6,1) + C(4,5)*DN_v(6,0) + crLHS467; + const double crLHS469 = DN_v(6,2)*crLHS354; + const double crLHS470 = C(1,2)*DDN_v[6](1,2) + C(1,5)*DDN_v[6](1,0) + C(2,3)*DDN_v[6](1,2) + C(2,4)*DDN_v[6](1,2) + C(3,5)*DDN_v[6](1,0) + C(4,4)*DDN_v[6](1,1) + C(4,5)*DDN_v[6](1,0) + crLHS456 + crLHS463; + const double crLHS471 = C(0,1)*DN_v(7,0) + C(1,5)*DN_v(7,2) + crLHS252; + const double crLHS472 = C(0,4)*DN_v(7,0) + crLHS255 + crLHS261; + const double crLHS473 = DN_v(7,0)*crLHS354; + const double crLHS474 = C(1,3)*DDN_v[7](1,1); + const double crLHS475 = C(3,4)*DDN_v[7](1,1); + const double crLHS476 = C(0,1)*DDN_v[7](1,0) + C(0,3)*DDN_v[7](1,0) + C(0,4)*DDN_v[7](1,0) + C(1,5)*DDN_v[7](1,2) + C(3,3)*DDN_v[7](1,1) + C(3,5)*DDN_v[7](1,2) + C(4,5)*DDN_v[7](1,2) + crLHS474 + crLHS475; + const double crLHS477 = C(1,1)*DN_v(7,1) + C(1,3)*DN_v(7,0) + C(1,4)*DN_v(7,2); + const double crLHS478 = C(1,4)*DN_v(7,1); + const double crLHS479 = C(3,4)*DN_v(7,0) + C(4,4)*DN_v(7,2) + crLHS478; + const double crLHS480 = DN_v(7,1)*crLHS354; + const double crLHS481 = 1.0*DDN_v[7](1,0); + const double crLHS482 = C(1,4)*DDN_v[7](1,1); + const double crLHS483 = 1.0*DDN_v[7](1,2); + const double crLHS484 = C(1,3)*crLHS481 + C(1,4)*crLHS483 + C(3,3)*crLHS481 + C(3,4)*crLHS481 + C(3,4)*crLHS483 + C(4,4)*crLHS483 + DDN_v[7](1,1)*crLHS346 + crLHS247 + 1.0*crLHS474 + 1.0*crLHS482; + const double crLHS485 = C(1,2)*DN_v(7,2) + C(1,5)*DN_v(7,0) + crLHS478; + const double crLHS486 = C(2,4)*DN_v(7,2); + const double crLHS487 = C(4,4)*DN_v(7,1) + C(4,5)*DN_v(7,0) + crLHS486; + const double crLHS488 = DN_v(7,2)*crLHS354; + const double crLHS489 = C(1,2)*DDN_v[7](1,2) + C(1,5)*DDN_v[7](1,0) + C(2,3)*DDN_v[7](1,2) + C(2,4)*DDN_v[7](1,2) + C(3,5)*DDN_v[7](1,0) + C(4,4)*DDN_v[7](1,1) + C(4,5)*DDN_v[7](1,0) + crLHS475 + crLHS482; + const double crLHS490 = C(0,1)*DN_v(8,0) + C(1,5)*DN_v(8,2) + crLHS284; + const double crLHS491 = C(0,4)*DN_v(8,0) + crLHS287 + crLHS293; + const double crLHS492 = DN_v(8,0)*crLHS354; + const double crLHS493 = C(1,3)*DDN_v[8](1,1); + const double crLHS494 = C(3,4)*DDN_v[8](1,1); + const double crLHS495 = C(0,1)*DDN_v[8](1,0) + C(0,3)*DDN_v[8](1,0) + C(0,4)*DDN_v[8](1,0) + C(1,5)*DDN_v[8](1,2) + C(3,3)*DDN_v[8](1,1) + C(3,5)*DDN_v[8](1,2) + C(4,5)*DDN_v[8](1,2) + crLHS493 + crLHS494; + const double crLHS496 = C(1,1)*DN_v(8,1) + C(1,3)*DN_v(8,0) + C(1,4)*DN_v(8,2); + const double crLHS497 = C(1,4)*DN_v(8,1); + const double crLHS498 = C(3,4)*DN_v(8,0) + C(4,4)*DN_v(8,2) + crLHS497; + const double crLHS499 = DN_v(8,1)*crLHS354; + const double crLHS500 = 1.0*DDN_v[8](1,0); + const double crLHS501 = C(1,4)*DDN_v[8](1,1); + const double crLHS502 = 1.0*DDN_v[8](1,2); + const double crLHS503 = C(1,3)*crLHS500 + C(1,4)*crLHS502 + C(3,3)*crLHS500 + C(3,4)*crLHS500 + C(3,4)*crLHS502 + C(4,4)*crLHS502 + DDN_v[8](1,1)*crLHS346 + crLHS279 + 1.0*crLHS493 + 1.0*crLHS501; + const double crLHS504 = C(1,2)*DN_v(8,2) + C(1,5)*DN_v(8,0) + crLHS497; + const double crLHS505 = C(2,4)*DN_v(8,2); + const double crLHS506 = C(4,4)*DN_v(8,1) + C(4,5)*DN_v(8,0) + crLHS505; + const double crLHS507 = DN_v(8,2)*crLHS354; + const double crLHS508 = C(1,2)*DDN_v[8](1,2) + C(1,5)*DDN_v[8](1,0) + C(2,3)*DDN_v[8](1,2) + C(2,4)*DDN_v[8](1,2) + C(3,5)*DDN_v[8](1,0) + C(4,4)*DDN_v[8](1,1) + C(4,5)*DDN_v[8](1,0) + crLHS494 + crLHS501; + const double crLHS509 = C(0,1)*DN_v(9,0) + C(1,5)*DN_v(9,2) + crLHS315; + const double crLHS510 = C(0,4)*DN_v(9,0) + crLHS318 + crLHS324; + const double crLHS511 = DN_v(9,0)*crLHS354; + const double crLHS512 = C(1,3)*DDN_v[9](1,1); + const double crLHS513 = C(3,4)*DDN_v[9](1,1); + const double crLHS514 = C(0,1)*DDN_v[9](1,0) + C(0,3)*DDN_v[9](1,0) + C(0,4)*DDN_v[9](1,0) + C(1,5)*DDN_v[9](1,2) + C(3,3)*DDN_v[9](1,1) + C(3,5)*DDN_v[9](1,2) + C(4,5)*DDN_v[9](1,2) + crLHS512 + crLHS513; + const double crLHS515 = C(1,1)*DN_v(9,1) + C(1,3)*DN_v(9,0) + C(1,4)*DN_v(9,2); + const double crLHS516 = C(1,4)*DN_v(9,1); + const double crLHS517 = C(3,4)*DN_v(9,0) + C(4,4)*DN_v(9,2) + crLHS516; + const double crLHS518 = DN_v(9,1)*crLHS354; + const double crLHS519 = 1.0*DDN_v[9](1,0); + const double crLHS520 = C(1,4)*DDN_v[9](1,1); + const double crLHS521 = 1.0*DDN_v[9](1,2); + const double crLHS522 = C(1,3)*crLHS519 + C(1,4)*crLHS521 + C(3,3)*crLHS519 + C(3,4)*crLHS519 + C(3,4)*crLHS521 + C(4,4)*crLHS521 + DDN_v[9](1,1)*crLHS346 + crLHS310 + 1.0*crLHS512 + 1.0*crLHS520; + const double crLHS523 = C(1,2)*DN_v(9,2) + C(1,5)*DN_v(9,0) + crLHS516; + const double crLHS524 = C(2,4)*DN_v(9,2); + const double crLHS525 = C(4,4)*DN_v(9,1) + C(4,5)*DN_v(9,0) + crLHS524; + const double crLHS526 = DN_v(9,2)*crLHS354; + const double crLHS527 = C(1,2)*DDN_v[9](1,2) + C(1,5)*DDN_v[9](1,0) + C(2,3)*DDN_v[9](1,2) + C(2,4)*DDN_v[9](1,2) + C(3,5)*DDN_v[9](1,0) + C(4,4)*DDN_v[9](1,1) + C(4,5)*DDN_v[9](1,0) + crLHS513 + crLHS520; + const double crLHS528 = -DN_v(0,1)*N_p[0]; + const double crLHS529 = DN_p(0,1)*crLHS20; + const double crLHS530 = -DN_v(0,1)*N_p[1]; + const double crLHS531 = DN_p(1,1)*crLHS20; + const double crLHS532 = -DN_v(0,1)*N_p[2]; + const double crLHS533 = DN_p(2,1)*crLHS20; + const double crLHS534 = -DN_v(0,1)*N_p[3]; + const double crLHS535 = DN_p(3,1)*crLHS20; + const double crLHS536 = C(0,2)*DN_v(0,0) + C(2,3)*DN_v(0,1) + crLHS39; + const double crLHS537 = C(2,5)*DDN_v[0](2,2); + const double crLHS538 = C(4,5)*DDN_v[0](2,2); + const double crLHS539 = C(0,2)*DDN_v[0](2,0) + C(0,4)*DDN_v[0](2,0) + C(0,5)*DDN_v[0](2,0) + C(2,3)*DDN_v[0](2,1) + C(3,4)*DDN_v[0](2,1) + C(3,5)*DDN_v[0](2,1) + C(5,5)*DDN_v[0](2,2) + crLHS537 + crLHS538; + const double crLHS540 = C(1,2)*DN_v(0,1) + C(2,3)*DN_v(0,0) + crLHS352; + const double crLHS541 = C(2,4)*DDN_v[0](2,2); + const double crLHS542 = C(1,2)*DDN_v[0](2,1) + C(1,4)*DDN_v[0](2,1) + C(1,5)*DDN_v[0](2,1) + C(2,3)*DDN_v[0](2,0) + C(3,4)*DDN_v[0](2,0) + C(3,5)*DDN_v[0](2,0) + C(4,4)*DDN_v[0](2,2) + crLHS538 + crLHS541; + const double crLHS543 = C(2,2)*DN_v(0,2) + C(2,4)*DN_v(0,1) + C(2,5)*DN_v(0,0); + const double crLHS544 = 1.0*C(2,2); + const double crLHS545 = 1.0*DDN_v[0](2,1); + const double crLHS546 = 1.0*DDN_v[0](2,0); + const double crLHS547 = C(2,4)*crLHS545 + C(2,5)*crLHS546 + C(4,4)*crLHS545 + C(4,5)*crLHS545 + C(4,5)*crLHS546 + C(5,5)*crLHS546 + DDN_v[0](2,2)*crLHS544 + crLHS18 + 1.0*crLHS537 + 1.0*crLHS541; + const double crLHS548 = C(0,2)*DN_v(1,0) + C(2,3)*DN_v(1,1) + crLHS71; + const double crLHS549 = DN_v(0,2)*crLHS9; + const double crLHS550 = DN_v(1,0)*crLHS549; + const double crLHS551 = C(2,5)*DDN_v[1](2,2); + const double crLHS552 = C(4,5)*DDN_v[1](2,2); + const double crLHS553 = C(0,2)*DDN_v[1](2,0) + C(0,4)*DDN_v[1](2,0) + C(0,5)*DDN_v[1](2,0) + C(2,3)*DDN_v[1](2,1) + C(3,4)*DDN_v[1](2,1) + C(3,5)*DDN_v[1](2,1) + C(5,5)*DDN_v[1](2,2) + crLHS551 + crLHS552; + const double crLHS554 = C(1,2)*DN_v(1,1) + C(2,3)*DN_v(1,0) + crLHS372; + const double crLHS555 = DN_v(1,1)*crLHS549; + const double crLHS556 = C(2,4)*DDN_v[1](2,2); + const double crLHS557 = C(1,2)*DDN_v[1](2,1) + C(1,4)*DDN_v[1](2,1) + C(1,5)*DDN_v[1](2,1) + C(2,3)*DDN_v[1](2,0) + C(3,4)*DDN_v[1](2,0) + C(3,5)*DDN_v[1](2,0) + C(4,4)*DDN_v[1](2,2) + crLHS552 + crLHS556; + const double crLHS558 = C(2,2)*DN_v(1,2) + C(2,4)*DN_v(1,1) + C(2,5)*DN_v(1,0); + const double crLHS559 = DN_v(1,2)*crLHS549; + const double crLHS560 = 1.0*DDN_v[1](2,1); + const double crLHS561 = 1.0*DDN_v[1](2,0); + const double crLHS562 = C(2,4)*crLHS560 + C(2,5)*crLHS561 + C(4,4)*crLHS560 + C(4,5)*crLHS560 + C(4,5)*crLHS561 + C(5,5)*crLHS561 + DDN_v[1](2,2)*crLHS544 + crLHS55 + 1.0*crLHS551 + 1.0*crLHS556; + const double crLHS563 = C(0,2)*DN_v(2,0) + C(2,3)*DN_v(2,1) + crLHS103; + const double crLHS564 = DN_v(2,0)*crLHS549; + const double crLHS565 = C(2,5)*DDN_v[2](2,2); + const double crLHS566 = C(4,5)*DDN_v[2](2,2); + const double crLHS567 = C(0,2)*DDN_v[2](2,0) + C(0,4)*DDN_v[2](2,0) + C(0,5)*DDN_v[2](2,0) + C(2,3)*DDN_v[2](2,1) + C(3,4)*DDN_v[2](2,1) + C(3,5)*DDN_v[2](2,1) + C(5,5)*DDN_v[2](2,2) + crLHS565 + crLHS566; + const double crLHS568 = C(1,2)*DN_v(2,1) + C(2,3)*DN_v(2,0) + crLHS391; + const double crLHS569 = DN_v(2,1)*crLHS549; + const double crLHS570 = C(2,4)*DDN_v[2](2,2); + const double crLHS571 = C(1,2)*DDN_v[2](2,1) + C(1,4)*DDN_v[2](2,1) + C(1,5)*DDN_v[2](2,1) + C(2,3)*DDN_v[2](2,0) + C(3,4)*DDN_v[2](2,0) + C(3,5)*DDN_v[2](2,0) + C(4,4)*DDN_v[2](2,2) + crLHS566 + crLHS570; + const double crLHS572 = C(2,2)*DN_v(2,2) + C(2,4)*DN_v(2,1) + C(2,5)*DN_v(2,0); + const double crLHS573 = DN_v(2,2)*crLHS549; + const double crLHS574 = 1.0*DDN_v[2](2,1); + const double crLHS575 = 1.0*DDN_v[2](2,0); + const double crLHS576 = C(2,4)*crLHS574 + C(2,5)*crLHS575 + C(4,4)*crLHS574 + C(4,5)*crLHS574 + C(4,5)*crLHS575 + C(5,5)*crLHS575 + DDN_v[2](2,2)*crLHS544 + 1.0*crLHS565 + 1.0*crLHS570 + crLHS87; + const double crLHS577 = C(0,2)*DN_v(3,0) + C(2,3)*DN_v(3,1) + crLHS135; + const double crLHS578 = DN_v(3,0)*crLHS549; + const double crLHS579 = C(2,5)*DDN_v[3](2,2); + const double crLHS580 = C(4,5)*DDN_v[3](2,2); + const double crLHS581 = C(0,2)*DDN_v[3](2,0) + C(0,4)*DDN_v[3](2,0) + C(0,5)*DDN_v[3](2,0) + C(2,3)*DDN_v[3](2,1) + C(3,4)*DDN_v[3](2,1) + C(3,5)*DDN_v[3](2,1) + C(5,5)*DDN_v[3](2,2) + crLHS579 + crLHS580; + const double crLHS582 = C(1,2)*DN_v(3,1) + C(2,3)*DN_v(3,0) + crLHS410; + const double crLHS583 = DN_v(3,1)*crLHS549; + const double crLHS584 = C(2,4)*DDN_v[3](2,2); + const double crLHS585 = C(1,2)*DDN_v[3](2,1) + C(1,4)*DDN_v[3](2,1) + C(1,5)*DDN_v[3](2,1) + C(2,3)*DDN_v[3](2,0) + C(3,4)*DDN_v[3](2,0) + C(3,5)*DDN_v[3](2,0) + C(4,4)*DDN_v[3](2,2) + crLHS580 + crLHS584; + const double crLHS586 = C(2,2)*DN_v(3,2) + C(2,4)*DN_v(3,1) + C(2,5)*DN_v(3,0); + const double crLHS587 = DN_v(3,2)*crLHS549; + const double crLHS588 = 1.0*DDN_v[3](2,1); + const double crLHS589 = 1.0*DDN_v[3](2,0); + const double crLHS590 = C(2,4)*crLHS588 + C(2,5)*crLHS589 + C(4,4)*crLHS588 + C(4,5)*crLHS588 + C(4,5)*crLHS589 + C(5,5)*crLHS589 + DDN_v[3](2,2)*crLHS544 + crLHS119 + 1.0*crLHS579 + 1.0*crLHS584; + const double crLHS591 = C(0,2)*DN_v(4,0) + C(2,3)*DN_v(4,1) + crLHS167; + const double crLHS592 = DN_v(4,0)*crLHS549; + const double crLHS593 = C(2,5)*DDN_v[4](2,2); + const double crLHS594 = C(4,5)*DDN_v[4](2,2); + const double crLHS595 = C(0,2)*DDN_v[4](2,0) + C(0,4)*DDN_v[4](2,0) + C(0,5)*DDN_v[4](2,0) + C(2,3)*DDN_v[4](2,1) + C(3,4)*DDN_v[4](2,1) + C(3,5)*DDN_v[4](2,1) + C(5,5)*DDN_v[4](2,2) + crLHS593 + crLHS594; + const double crLHS596 = C(1,2)*DN_v(4,1) + C(2,3)*DN_v(4,0) + crLHS429; + const double crLHS597 = DN_v(4,1)*crLHS549; + const double crLHS598 = C(2,4)*DDN_v[4](2,2); + const double crLHS599 = C(1,2)*DDN_v[4](2,1) + C(1,4)*DDN_v[4](2,1) + C(1,5)*DDN_v[4](2,1) + C(2,3)*DDN_v[4](2,0) + C(3,4)*DDN_v[4](2,0) + C(3,5)*DDN_v[4](2,0) + C(4,4)*DDN_v[4](2,2) + crLHS594 + crLHS598; + const double crLHS600 = C(2,2)*DN_v(4,2) + C(2,4)*DN_v(4,1) + C(2,5)*DN_v(4,0); + const double crLHS601 = DN_v(4,2)*crLHS549; + const double crLHS602 = 1.0*DDN_v[4](2,1); + const double crLHS603 = 1.0*DDN_v[4](2,0); + const double crLHS604 = C(2,4)*crLHS602 + C(2,5)*crLHS603 + C(4,4)*crLHS602 + C(4,5)*crLHS602 + C(4,5)*crLHS603 + C(5,5)*crLHS603 + DDN_v[4](2,2)*crLHS544 + crLHS151 + 1.0*crLHS593 + 1.0*crLHS598; + const double crLHS605 = C(0,2)*DN_v(5,0) + C(2,3)*DN_v(5,1) + crLHS199; + const double crLHS606 = DN_v(5,0)*crLHS549; + const double crLHS607 = C(2,5)*DDN_v[5](2,2); + const double crLHS608 = C(4,5)*DDN_v[5](2,2); + const double crLHS609 = C(0,2)*DDN_v[5](2,0) + C(0,4)*DDN_v[5](2,0) + C(0,5)*DDN_v[5](2,0) + C(2,3)*DDN_v[5](2,1) + C(3,4)*DDN_v[5](2,1) + C(3,5)*DDN_v[5](2,1) + C(5,5)*DDN_v[5](2,2) + crLHS607 + crLHS608; + const double crLHS610 = C(1,2)*DN_v(5,1) + C(2,3)*DN_v(5,0) + crLHS448; + const double crLHS611 = DN_v(5,1)*crLHS549; + const double crLHS612 = C(2,4)*DDN_v[5](2,2); + const double crLHS613 = C(1,2)*DDN_v[5](2,1) + C(1,4)*DDN_v[5](2,1) + C(1,5)*DDN_v[5](2,1) + C(2,3)*DDN_v[5](2,0) + C(3,4)*DDN_v[5](2,0) + C(3,5)*DDN_v[5](2,0) + C(4,4)*DDN_v[5](2,2) + crLHS608 + crLHS612; + const double crLHS614 = C(2,2)*DN_v(5,2) + C(2,4)*DN_v(5,1) + C(2,5)*DN_v(5,0); + const double crLHS615 = DN_v(5,2)*crLHS549; + const double crLHS616 = 1.0*DDN_v[5](2,1); + const double crLHS617 = 1.0*DDN_v[5](2,0); + const double crLHS618 = C(2,4)*crLHS616 + C(2,5)*crLHS617 + C(4,4)*crLHS616 + C(4,5)*crLHS616 + C(4,5)*crLHS617 + C(5,5)*crLHS617 + DDN_v[5](2,2)*crLHS544 + crLHS183 + 1.0*crLHS607 + 1.0*crLHS612; + const double crLHS619 = C(0,2)*DN_v(6,0) + C(2,3)*DN_v(6,1) + crLHS231; + const double crLHS620 = DN_v(6,0)*crLHS549; + const double crLHS621 = C(2,5)*DDN_v[6](2,2); + const double crLHS622 = C(4,5)*DDN_v[6](2,2); + const double crLHS623 = C(0,2)*DDN_v[6](2,0) + C(0,4)*DDN_v[6](2,0) + C(0,5)*DDN_v[6](2,0) + C(2,3)*DDN_v[6](2,1) + C(3,4)*DDN_v[6](2,1) + C(3,5)*DDN_v[6](2,1) + C(5,5)*DDN_v[6](2,2) + crLHS621 + crLHS622; + const double crLHS624 = C(1,2)*DN_v(6,1) + C(2,3)*DN_v(6,0) + crLHS467; + const double crLHS625 = DN_v(6,1)*crLHS549; + const double crLHS626 = C(2,4)*DDN_v[6](2,2); + const double crLHS627 = C(1,2)*DDN_v[6](2,1) + C(1,4)*DDN_v[6](2,1) + C(1,5)*DDN_v[6](2,1) + C(2,3)*DDN_v[6](2,0) + C(3,4)*DDN_v[6](2,0) + C(3,5)*DDN_v[6](2,0) + C(4,4)*DDN_v[6](2,2) + crLHS622 + crLHS626; + const double crLHS628 = C(2,2)*DN_v(6,2) + C(2,4)*DN_v(6,1) + C(2,5)*DN_v(6,0); + const double crLHS629 = DN_v(6,2)*crLHS549; + const double crLHS630 = 1.0*DDN_v[6](2,1); + const double crLHS631 = 1.0*DDN_v[6](2,0); + const double crLHS632 = C(2,4)*crLHS630 + C(2,5)*crLHS631 + C(4,4)*crLHS630 + C(4,5)*crLHS630 + C(4,5)*crLHS631 + C(5,5)*crLHS631 + DDN_v[6](2,2)*crLHS544 + crLHS215 + 1.0*crLHS621 + 1.0*crLHS626; + const double crLHS633 = C(0,2)*DN_v(7,0) + C(2,3)*DN_v(7,1) + crLHS263; + const double crLHS634 = DN_v(7,0)*crLHS549; + const double crLHS635 = C(2,5)*DDN_v[7](2,2); + const double crLHS636 = C(4,5)*DDN_v[7](2,2); + const double crLHS637 = C(0,2)*DDN_v[7](2,0) + C(0,4)*DDN_v[7](2,0) + C(0,5)*DDN_v[7](2,0) + C(2,3)*DDN_v[7](2,1) + C(3,4)*DDN_v[7](2,1) + C(3,5)*DDN_v[7](2,1) + C(5,5)*DDN_v[7](2,2) + crLHS635 + crLHS636; + const double crLHS638 = C(1,2)*DN_v(7,1) + C(2,3)*DN_v(7,0) + crLHS486; + const double crLHS639 = DN_v(7,1)*crLHS549; + const double crLHS640 = C(2,4)*DDN_v[7](2,2); + const double crLHS641 = C(1,2)*DDN_v[7](2,1) + C(1,4)*DDN_v[7](2,1) + C(1,5)*DDN_v[7](2,1) + C(2,3)*DDN_v[7](2,0) + C(3,4)*DDN_v[7](2,0) + C(3,5)*DDN_v[7](2,0) + C(4,4)*DDN_v[7](2,2) + crLHS636 + crLHS640; + const double crLHS642 = C(2,2)*DN_v(7,2) + C(2,4)*DN_v(7,1) + C(2,5)*DN_v(7,0); + const double crLHS643 = DN_v(7,2)*crLHS549; + const double crLHS644 = 1.0*DDN_v[7](2,1); + const double crLHS645 = 1.0*DDN_v[7](2,0); + const double crLHS646 = C(2,4)*crLHS644 + C(2,5)*crLHS645 + C(4,4)*crLHS644 + C(4,5)*crLHS644 + C(4,5)*crLHS645 + C(5,5)*crLHS645 + DDN_v[7](2,2)*crLHS544 + crLHS247 + 1.0*crLHS635 + 1.0*crLHS640; + const double crLHS647 = C(0,2)*DN_v(8,0) + C(2,3)*DN_v(8,1) + crLHS295; + const double crLHS648 = DN_v(8,0)*crLHS549; + const double crLHS649 = C(2,5)*DDN_v[8](2,2); + const double crLHS650 = C(4,5)*DDN_v[8](2,2); + const double crLHS651 = C(0,2)*DDN_v[8](2,0) + C(0,4)*DDN_v[8](2,0) + C(0,5)*DDN_v[8](2,0) + C(2,3)*DDN_v[8](2,1) + C(3,4)*DDN_v[8](2,1) + C(3,5)*DDN_v[8](2,1) + C(5,5)*DDN_v[8](2,2) + crLHS649 + crLHS650; + const double crLHS652 = C(1,2)*DN_v(8,1) + C(2,3)*DN_v(8,0) + crLHS505; + const double crLHS653 = DN_v(8,1)*crLHS549; + const double crLHS654 = C(2,4)*DDN_v[8](2,2); + const double crLHS655 = C(1,2)*DDN_v[8](2,1) + C(1,4)*DDN_v[8](2,1) + C(1,5)*DDN_v[8](2,1) + C(2,3)*DDN_v[8](2,0) + C(3,4)*DDN_v[8](2,0) + C(3,5)*DDN_v[8](2,0) + C(4,4)*DDN_v[8](2,2) + crLHS650 + crLHS654; + const double crLHS656 = C(2,2)*DN_v(8,2) + C(2,4)*DN_v(8,1) + C(2,5)*DN_v(8,0); + const double crLHS657 = DN_v(8,2)*crLHS549; + const double crLHS658 = 1.0*DDN_v[8](2,1); + const double crLHS659 = 1.0*DDN_v[8](2,0); + const double crLHS660 = C(2,4)*crLHS658 + C(2,5)*crLHS659 + C(4,4)*crLHS658 + C(4,5)*crLHS658 + C(4,5)*crLHS659 + C(5,5)*crLHS659 + DDN_v[8](2,2)*crLHS544 + crLHS279 + 1.0*crLHS649 + 1.0*crLHS654; + const double crLHS661 = C(0,2)*DN_v(9,0) + C(2,3)*DN_v(9,1) + crLHS326; + const double crLHS662 = DN_v(9,0)*crLHS549; + const double crLHS663 = C(2,5)*DDN_v[9](2,2); + const double crLHS664 = C(4,5)*DDN_v[9](2,2); + const double crLHS665 = C(0,2)*DDN_v[9](2,0) + C(0,4)*DDN_v[9](2,0) + C(0,5)*DDN_v[9](2,0) + C(2,3)*DDN_v[9](2,1) + C(3,4)*DDN_v[9](2,1) + C(3,5)*DDN_v[9](2,1) + C(5,5)*DDN_v[9](2,2) + crLHS663 + crLHS664; + const double crLHS666 = C(1,2)*DN_v(9,1) + C(2,3)*DN_v(9,0) + crLHS524; + const double crLHS667 = DN_v(9,1)*crLHS549; + const double crLHS668 = C(2,4)*DDN_v[9](2,2); + const double crLHS669 = C(1,2)*DDN_v[9](2,1) + C(1,4)*DDN_v[9](2,1) + C(1,5)*DDN_v[9](2,1) + C(2,3)*DDN_v[9](2,0) + C(3,4)*DDN_v[9](2,0) + C(3,5)*DDN_v[9](2,0) + C(4,4)*DDN_v[9](2,2) + crLHS664 + crLHS668; + const double crLHS670 = C(2,2)*DN_v(9,2) + C(2,4)*DN_v(9,1) + C(2,5)*DN_v(9,0); + const double crLHS671 = DN_v(9,2)*crLHS549; + const double crLHS672 = 1.0*DDN_v[9](2,1); + const double crLHS673 = 1.0*DDN_v[9](2,0); + const double crLHS674 = C(2,4)*crLHS672 + C(2,5)*crLHS673 + C(4,4)*crLHS672 + C(4,5)*crLHS672 + C(4,5)*crLHS673 + C(5,5)*crLHS673 + DDN_v[9](2,2)*crLHS544 + crLHS310 + 1.0*crLHS663 + 1.0*crLHS668; + const double crLHS675 = -DN_v(0,2)*N_p[0]; + const double crLHS676 = DN_p(0,2)*crLHS20; + const double crLHS677 = -DN_v(0,2)*N_p[1]; + const double crLHS678 = DN_p(1,2)*crLHS20; + const double crLHS679 = -DN_v(0,2)*N_p[2]; + const double crLHS680 = DN_p(2,2)*crLHS20; + const double crLHS681 = -DN_v(0,2)*N_p[3]; + const double crLHS682 = DN_p(3,2)*crLHS20; + const double crLHS683 = crLHS20*crLHS53; + const double crLHS684 = N_v[1]*crLHS22; + const double crLHS685 = crLHS20*crLHS684; + const double crLHS686 = N_v[1]*crLHS15 + crLHS57; + const double crLHS687 = std::pow(N_v[1], 2)*crLHS16 + N_v[1]*crLHS53; + const double crLHS688 = DN_v(1,0)*crLHS9; + const double crLHS689 = DN_v(1,1)*crLHS688; + const double crLHS690 = DN_v(1,2)*crLHS688; + const double crLHS691 = DN_v(2,0)*crLHS688; + const double crLHS692 = N_v[2]*crLHS54; + const double crLHS693 = N_v[1]*crLHS85 + crLHS692; + const double crLHS694 = DN_v(2,1)*crLHS688; + const double crLHS695 = DN_v(2,2)*crLHS688; + const double crLHS696 = DN_v(3,0)*crLHS688; + const double crLHS697 = N_v[3]*crLHS54; + const double crLHS698 = N_v[1]*crLHS117 + crLHS697; + const double crLHS699 = DN_v(3,1)*crLHS688; + const double crLHS700 = DN_v(3,2)*crLHS688; + const double crLHS701 = DN_v(4,0)*crLHS688; + const double crLHS702 = N_v[4]*crLHS54; + const double crLHS703 = N_v[1]*crLHS149 + crLHS702; + const double crLHS704 = DN_v(4,1)*crLHS688; + const double crLHS705 = DN_v(4,2)*crLHS688; + const double crLHS706 = DN_v(5,0)*crLHS688; + const double crLHS707 = N_v[5]*crLHS54; + const double crLHS708 = N_v[1]*crLHS181 + crLHS707; + const double crLHS709 = DN_v(5,1)*crLHS688; + const double crLHS710 = DN_v(5,2)*crLHS688; + const double crLHS711 = DN_v(6,0)*crLHS688; + const double crLHS712 = N_v[6]*crLHS54; + const double crLHS713 = N_v[1]*crLHS213 + crLHS712; + const double crLHS714 = DN_v(6,1)*crLHS688; + const double crLHS715 = DN_v(6,2)*crLHS688; + const double crLHS716 = DN_v(7,0)*crLHS688; + const double crLHS717 = N_v[7]*crLHS54; + const double crLHS718 = N_v[1]*crLHS245 + crLHS717; + const double crLHS719 = DN_v(7,1)*crLHS688; + const double crLHS720 = DN_v(7,2)*crLHS688; + const double crLHS721 = DN_v(8,0)*crLHS688; + const double crLHS722 = N_v[8]*crLHS54; + const double crLHS723 = N_v[1]*crLHS277 + crLHS722; + const double crLHS724 = DN_v(8,1)*crLHS688; + const double crLHS725 = DN_v(8,2)*crLHS688; + const double crLHS726 = DN_v(9,0)*crLHS688; + const double crLHS727 = N_v[9]*crLHS54; + const double crLHS728 = N_v[1]*crLHS309 + crLHS727; + const double crLHS729 = DN_v(9,1)*crLHS688; + const double crLHS730 = DN_v(9,2)*crLHS688; + const double crLHS731 = -DN_v(1,0)*N_p[0]; + const double crLHS732 = -DN_v(1,0)*N_p[1]; + const double crLHS733 = -DN_v(1,0)*N_p[2]; + const double crLHS734 = -DN_v(1,0)*N_p[3]; + const double crLHS735 = DN_v(1,1)*crLHS9; + const double crLHS736 = DN_v(1,2)*crLHS735; + const double crLHS737 = DN_v(2,0)*crLHS735; + const double crLHS738 = DN_v(2,1)*crLHS735; + const double crLHS739 = DN_v(2,2)*crLHS735; + const double crLHS740 = DN_v(3,0)*crLHS735; + const double crLHS741 = DN_v(3,1)*crLHS735; + const double crLHS742 = DN_v(3,2)*crLHS735; + const double crLHS743 = DN_v(4,0)*crLHS735; + const double crLHS744 = DN_v(4,1)*crLHS735; + const double crLHS745 = DN_v(4,2)*crLHS735; + const double crLHS746 = DN_v(5,0)*crLHS735; + const double crLHS747 = DN_v(5,1)*crLHS735; + const double crLHS748 = DN_v(5,2)*crLHS735; + const double crLHS749 = DN_v(6,0)*crLHS735; + const double crLHS750 = DN_v(6,1)*crLHS735; + const double crLHS751 = DN_v(6,2)*crLHS735; + const double crLHS752 = DN_v(7,0)*crLHS735; + const double crLHS753 = DN_v(7,1)*crLHS735; + const double crLHS754 = DN_v(7,2)*crLHS735; + const double crLHS755 = DN_v(8,0)*crLHS735; + const double crLHS756 = DN_v(8,1)*crLHS735; + const double crLHS757 = DN_v(8,2)*crLHS735; + const double crLHS758 = DN_v(9,0)*crLHS735; + const double crLHS759 = DN_v(9,1)*crLHS735; + const double crLHS760 = DN_v(9,2)*crLHS735; + const double crLHS761 = -DN_v(1,1)*N_p[0]; + const double crLHS762 = -DN_v(1,1)*N_p[1]; + const double crLHS763 = -DN_v(1,1)*N_p[2]; + const double crLHS764 = -DN_v(1,1)*N_p[3]; + const double crLHS765 = DN_v(1,2)*crLHS9; + const double crLHS766 = DN_v(2,0)*crLHS765; + const double crLHS767 = DN_v(2,1)*crLHS765; + const double crLHS768 = DN_v(2,2)*crLHS765; + const double crLHS769 = DN_v(3,0)*crLHS765; + const double crLHS770 = DN_v(3,1)*crLHS765; + const double crLHS771 = DN_v(3,2)*crLHS765; + const double crLHS772 = DN_v(4,0)*crLHS765; + const double crLHS773 = DN_v(4,1)*crLHS765; + const double crLHS774 = DN_v(4,2)*crLHS765; + const double crLHS775 = DN_v(5,0)*crLHS765; + const double crLHS776 = DN_v(5,1)*crLHS765; + const double crLHS777 = DN_v(5,2)*crLHS765; + const double crLHS778 = DN_v(6,0)*crLHS765; + const double crLHS779 = DN_v(6,1)*crLHS765; + const double crLHS780 = DN_v(6,2)*crLHS765; + const double crLHS781 = DN_v(7,0)*crLHS765; + const double crLHS782 = DN_v(7,1)*crLHS765; + const double crLHS783 = DN_v(7,2)*crLHS765; + const double crLHS784 = DN_v(8,0)*crLHS765; + const double crLHS785 = DN_v(8,1)*crLHS765; + const double crLHS786 = DN_v(8,2)*crLHS765; + const double crLHS787 = DN_v(9,0)*crLHS765; + const double crLHS788 = DN_v(9,1)*crLHS765; + const double crLHS789 = DN_v(9,2)*crLHS765; + const double crLHS790 = -DN_v(1,2)*N_p[0]; + const double crLHS791 = -DN_v(1,2)*N_p[1]; + const double crLHS792 = -DN_v(1,2)*N_p[2]; + const double crLHS793 = -DN_v(1,2)*N_p[3]; + const double crLHS794 = crLHS20*crLHS85; + const double crLHS795 = N_v[2]*crLHS22; + const double crLHS796 = crLHS20*crLHS795; + const double crLHS797 = N_v[2]*crLHS15 + crLHS89; + const double crLHS798 = N_v[2]*crLHS53 + crLHS692; + const double crLHS799 = std::pow(N_v[2], 2)*crLHS16 + N_v[2]*crLHS85; + const double crLHS800 = DN_v(2,0)*crLHS9; + const double crLHS801 = DN_v(2,1)*crLHS800; + const double crLHS802 = DN_v(2,2)*crLHS800; + const double crLHS803 = DN_v(3,0)*crLHS800; + const double crLHS804 = N_v[3]*crLHS86; + const double crLHS805 = N_v[2]*crLHS117 + crLHS804; + const double crLHS806 = DN_v(3,1)*crLHS800; + const double crLHS807 = DN_v(3,2)*crLHS800; + const double crLHS808 = DN_v(4,0)*crLHS800; + const double crLHS809 = N_v[4]*crLHS86; + const double crLHS810 = N_v[2]*crLHS149 + crLHS809; + const double crLHS811 = DN_v(4,1)*crLHS800; + const double crLHS812 = DN_v(4,2)*crLHS800; + const double crLHS813 = DN_v(5,0)*crLHS800; + const double crLHS814 = N_v[5]*crLHS86; + const double crLHS815 = N_v[2]*crLHS181 + crLHS814; + const double crLHS816 = DN_v(5,1)*crLHS800; + const double crLHS817 = DN_v(5,2)*crLHS800; + const double crLHS818 = DN_v(6,0)*crLHS800; + const double crLHS819 = N_v[6]*crLHS86; + const double crLHS820 = N_v[2]*crLHS213 + crLHS819; + const double crLHS821 = DN_v(6,1)*crLHS800; + const double crLHS822 = DN_v(6,2)*crLHS800; + const double crLHS823 = DN_v(7,0)*crLHS800; + const double crLHS824 = N_v[7]*crLHS86; + const double crLHS825 = N_v[2]*crLHS245 + crLHS824; + const double crLHS826 = DN_v(7,1)*crLHS800; + const double crLHS827 = DN_v(7,2)*crLHS800; + const double crLHS828 = DN_v(8,0)*crLHS800; + const double crLHS829 = N_v[8]*crLHS86; + const double crLHS830 = N_v[2]*crLHS277 + crLHS829; + const double crLHS831 = DN_v(8,1)*crLHS800; + const double crLHS832 = DN_v(8,2)*crLHS800; + const double crLHS833 = DN_v(9,0)*crLHS800; + const double crLHS834 = N_v[9]*crLHS86; + const double crLHS835 = N_v[2]*crLHS309 + crLHS834; + const double crLHS836 = DN_v(9,1)*crLHS800; + const double crLHS837 = DN_v(9,2)*crLHS800; + const double crLHS838 = -DN_v(2,0)*N_p[0]; + const double crLHS839 = -DN_v(2,0)*N_p[1]; + const double crLHS840 = -DN_v(2,0)*N_p[2]; + const double crLHS841 = -DN_v(2,0)*N_p[3]; + const double crLHS842 = DN_v(2,1)*crLHS9; + const double crLHS843 = DN_v(2,2)*crLHS842; + const double crLHS844 = DN_v(3,0)*crLHS842; + const double crLHS845 = DN_v(3,1)*crLHS842; + const double crLHS846 = DN_v(3,2)*crLHS842; + const double crLHS847 = DN_v(4,0)*crLHS842; + const double crLHS848 = DN_v(4,1)*crLHS842; + const double crLHS849 = DN_v(4,2)*crLHS842; + const double crLHS850 = DN_v(5,0)*crLHS842; + const double crLHS851 = DN_v(5,1)*crLHS842; + const double crLHS852 = DN_v(5,2)*crLHS842; + const double crLHS853 = DN_v(6,0)*crLHS842; + const double crLHS854 = DN_v(6,1)*crLHS842; + const double crLHS855 = DN_v(6,2)*crLHS842; + const double crLHS856 = DN_v(7,0)*crLHS842; + const double crLHS857 = DN_v(7,1)*crLHS842; + const double crLHS858 = DN_v(7,2)*crLHS842; + const double crLHS859 = DN_v(8,0)*crLHS842; + const double crLHS860 = DN_v(8,1)*crLHS842; + const double crLHS861 = DN_v(8,2)*crLHS842; + const double crLHS862 = DN_v(9,0)*crLHS842; + const double crLHS863 = DN_v(9,1)*crLHS842; + const double crLHS864 = DN_v(9,2)*crLHS842; + const double crLHS865 = -DN_v(2,1)*N_p[0]; + const double crLHS866 = -DN_v(2,1)*N_p[1]; + const double crLHS867 = -DN_v(2,1)*N_p[2]; + const double crLHS868 = -DN_v(2,1)*N_p[3]; + const double crLHS869 = DN_v(2,2)*crLHS9; + const double crLHS870 = DN_v(3,0)*crLHS869; + const double crLHS871 = DN_v(3,1)*crLHS869; + const double crLHS872 = DN_v(3,2)*crLHS869; + const double crLHS873 = DN_v(4,0)*crLHS869; + const double crLHS874 = DN_v(4,1)*crLHS869; + const double crLHS875 = DN_v(4,2)*crLHS869; + const double crLHS876 = DN_v(5,0)*crLHS869; + const double crLHS877 = DN_v(5,1)*crLHS869; + const double crLHS878 = DN_v(5,2)*crLHS869; + const double crLHS879 = DN_v(6,0)*crLHS869; + const double crLHS880 = DN_v(6,1)*crLHS869; + const double crLHS881 = DN_v(6,2)*crLHS869; + const double crLHS882 = DN_v(7,0)*crLHS869; + const double crLHS883 = DN_v(7,1)*crLHS869; + const double crLHS884 = DN_v(7,2)*crLHS869; + const double crLHS885 = DN_v(8,0)*crLHS869; + const double crLHS886 = DN_v(8,1)*crLHS869; + const double crLHS887 = DN_v(8,2)*crLHS869; + const double crLHS888 = DN_v(9,0)*crLHS869; + const double crLHS889 = DN_v(9,1)*crLHS869; + const double crLHS890 = DN_v(9,2)*crLHS869; + const double crLHS891 = -DN_v(2,2)*N_p[0]; + const double crLHS892 = -DN_v(2,2)*N_p[1]; + const double crLHS893 = -DN_v(2,2)*N_p[2]; + const double crLHS894 = -DN_v(2,2)*N_p[3]; + const double crLHS895 = crLHS117*crLHS20; + const double crLHS896 = N_v[3]*crLHS22; + const double crLHS897 = crLHS20*crLHS896; + const double crLHS898 = N_v[3]*crLHS15 + crLHS121; + const double crLHS899 = N_v[3]*crLHS53 + crLHS697; + const double crLHS900 = N_v[3]*crLHS85 + crLHS804; + const double crLHS901 = std::pow(N_v[3], 2)*crLHS16 + N_v[3]*crLHS117; + const double crLHS902 = DN_v(3,0)*crLHS9; + const double crLHS903 = DN_v(3,1)*crLHS902; + const double crLHS904 = DN_v(3,2)*crLHS902; + const double crLHS905 = DN_v(4,0)*crLHS902; + const double crLHS906 = N_v[4]*crLHS118; + const double crLHS907 = N_v[3]*crLHS149 + crLHS906; + const double crLHS908 = DN_v(4,1)*crLHS902; + const double crLHS909 = DN_v(4,2)*crLHS902; + const double crLHS910 = DN_v(5,0)*crLHS902; + const double crLHS911 = N_v[5]*crLHS118; + const double crLHS912 = N_v[3]*crLHS181 + crLHS911; + const double crLHS913 = DN_v(5,1)*crLHS902; + const double crLHS914 = DN_v(5,2)*crLHS902; + const double crLHS915 = DN_v(6,0)*crLHS902; + const double crLHS916 = N_v[6]*crLHS118; + const double crLHS917 = N_v[3]*crLHS213 + crLHS916; + const double crLHS918 = DN_v(6,1)*crLHS902; + const double crLHS919 = DN_v(6,2)*crLHS902; + const double crLHS920 = DN_v(7,0)*crLHS902; + const double crLHS921 = N_v[7]*crLHS118; + const double crLHS922 = N_v[3]*crLHS245 + crLHS921; + const double crLHS923 = DN_v(7,1)*crLHS902; + const double crLHS924 = DN_v(7,2)*crLHS902; + const double crLHS925 = DN_v(8,0)*crLHS902; + const double crLHS926 = N_v[8]*crLHS118; + const double crLHS927 = N_v[3]*crLHS277 + crLHS926; + const double crLHS928 = DN_v(8,1)*crLHS902; + const double crLHS929 = DN_v(8,2)*crLHS902; + const double crLHS930 = DN_v(9,0)*crLHS902; + const double crLHS931 = N_v[9]*crLHS118; + const double crLHS932 = N_v[3]*crLHS309 + crLHS931; + const double crLHS933 = DN_v(9,1)*crLHS902; + const double crLHS934 = DN_v(9,2)*crLHS902; + const double crLHS935 = -DN_v(3,0)*N_p[0]; + const double crLHS936 = -DN_v(3,0)*N_p[1]; + const double crLHS937 = -DN_v(3,0)*N_p[2]; + const double crLHS938 = -DN_v(3,0)*N_p[3]; + const double crLHS939 = DN_v(3,1)*crLHS9; + const double crLHS940 = DN_v(3,2)*crLHS939; + const double crLHS941 = DN_v(4,0)*crLHS939; + const double crLHS942 = DN_v(4,1)*crLHS939; + const double crLHS943 = DN_v(4,2)*crLHS939; + const double crLHS944 = DN_v(5,0)*crLHS939; + const double crLHS945 = DN_v(5,1)*crLHS939; + const double crLHS946 = DN_v(5,2)*crLHS939; + const double crLHS947 = DN_v(6,0)*crLHS939; + const double crLHS948 = DN_v(6,1)*crLHS939; + const double crLHS949 = DN_v(6,2)*crLHS939; + const double crLHS950 = DN_v(7,0)*crLHS939; + const double crLHS951 = DN_v(7,1)*crLHS939; + const double crLHS952 = DN_v(7,2)*crLHS939; + const double crLHS953 = DN_v(8,0)*crLHS939; + const double crLHS954 = DN_v(8,1)*crLHS939; + const double crLHS955 = DN_v(8,2)*crLHS939; + const double crLHS956 = DN_v(9,0)*crLHS939; + const double crLHS957 = DN_v(9,1)*crLHS939; + const double crLHS958 = DN_v(9,2)*crLHS939; + const double crLHS959 = -DN_v(3,1)*N_p[0]; + const double crLHS960 = -DN_v(3,1)*N_p[1]; + const double crLHS961 = -DN_v(3,1)*N_p[2]; + const double crLHS962 = -DN_v(3,1)*N_p[3]; + const double crLHS963 = DN_v(3,2)*crLHS9; + const double crLHS964 = DN_v(4,0)*crLHS963; + const double crLHS965 = DN_v(4,1)*crLHS963; + const double crLHS966 = DN_v(4,2)*crLHS963; + const double crLHS967 = DN_v(5,0)*crLHS963; + const double crLHS968 = DN_v(5,1)*crLHS963; + const double crLHS969 = DN_v(5,2)*crLHS963; + const double crLHS970 = DN_v(6,0)*crLHS963; + const double crLHS971 = DN_v(6,1)*crLHS963; + const double crLHS972 = DN_v(6,2)*crLHS963; + const double crLHS973 = DN_v(7,0)*crLHS963; + const double crLHS974 = DN_v(7,1)*crLHS963; + const double crLHS975 = DN_v(7,2)*crLHS963; + const double crLHS976 = DN_v(8,0)*crLHS963; + const double crLHS977 = DN_v(8,1)*crLHS963; + const double crLHS978 = DN_v(8,2)*crLHS963; + const double crLHS979 = DN_v(9,0)*crLHS963; + const double crLHS980 = DN_v(9,1)*crLHS963; + const double crLHS981 = DN_v(9,2)*crLHS963; + const double crLHS982 = -DN_v(3,2)*N_p[0]; + const double crLHS983 = -DN_v(3,2)*N_p[1]; + const double crLHS984 = -DN_v(3,2)*N_p[2]; + const double crLHS985 = -DN_v(3,2)*N_p[3]; + const double crLHS986 = crLHS149*crLHS20; + const double crLHS987 = N_v[4]*crLHS22; + const double crLHS988 = crLHS20*crLHS987; + const double crLHS989 = N_v[4]*crLHS15 + crLHS153; + const double crLHS990 = N_v[4]*crLHS53 + crLHS702; + const double crLHS991 = N_v[4]*crLHS85 + crLHS809; + const double crLHS992 = N_v[4]*crLHS117 + crLHS906; + const double crLHS993 = std::pow(N_v[4], 2)*crLHS16 + N_v[4]*crLHS149; + const double crLHS994 = DN_v(4,0)*crLHS9; + const double crLHS995 = DN_v(4,1)*crLHS994; + const double crLHS996 = DN_v(4,2)*crLHS994; + const double crLHS997 = DN_v(5,0)*crLHS994; + const double crLHS998 = N_v[5]*crLHS150; + const double crLHS999 = N_v[4]*crLHS181 + crLHS998; + const double crLHS1000 = DN_v(5,1)*crLHS994; + const double crLHS1001 = DN_v(5,2)*crLHS994; + const double crLHS1002 = DN_v(6,0)*crLHS994; + const double crLHS1003 = N_v[6]*crLHS150; + const double crLHS1004 = N_v[4]*crLHS213 + crLHS1003; + const double crLHS1005 = DN_v(6,1)*crLHS994; + const double crLHS1006 = DN_v(6,2)*crLHS994; + const double crLHS1007 = DN_v(7,0)*crLHS994; + const double crLHS1008 = N_v[7]*crLHS150; + const double crLHS1009 = N_v[4]*crLHS245 + crLHS1008; + const double crLHS1010 = DN_v(7,1)*crLHS994; + const double crLHS1011 = DN_v(7,2)*crLHS994; + const double crLHS1012 = DN_v(8,0)*crLHS994; + const double crLHS1013 = N_v[8]*crLHS150; + const double crLHS1014 = N_v[4]*crLHS277 + crLHS1013; + const double crLHS1015 = DN_v(8,1)*crLHS994; + const double crLHS1016 = DN_v(8,2)*crLHS994; + const double crLHS1017 = DN_v(9,0)*crLHS994; + const double crLHS1018 = N_v[9]*crLHS150; + const double crLHS1019 = N_v[4]*crLHS309 + crLHS1018; + const double crLHS1020 = DN_v(9,1)*crLHS994; + const double crLHS1021 = DN_v(9,2)*crLHS994; + const double crLHS1022 = -DN_v(4,0)*N_p[0]; + const double crLHS1023 = -DN_v(4,0)*N_p[1]; + const double crLHS1024 = -DN_v(4,0)*N_p[2]; + const double crLHS1025 = -DN_v(4,0)*N_p[3]; + const double crLHS1026 = DN_v(4,1)*crLHS9; + const double crLHS1027 = DN_v(4,2)*crLHS1026; + const double crLHS1028 = DN_v(5,0)*crLHS1026; + const double crLHS1029 = DN_v(5,1)*crLHS1026; + const double crLHS1030 = DN_v(5,2)*crLHS1026; + const double crLHS1031 = DN_v(6,0)*crLHS1026; + const double crLHS1032 = DN_v(6,1)*crLHS1026; + const double crLHS1033 = DN_v(6,2)*crLHS1026; + const double crLHS1034 = DN_v(7,0)*crLHS1026; + const double crLHS1035 = DN_v(7,1)*crLHS1026; + const double crLHS1036 = DN_v(7,2)*crLHS1026; + const double crLHS1037 = DN_v(8,0)*crLHS1026; + const double crLHS1038 = DN_v(8,1)*crLHS1026; + const double crLHS1039 = DN_v(8,2)*crLHS1026; + const double crLHS1040 = DN_v(9,0)*crLHS1026; + const double crLHS1041 = DN_v(9,1)*crLHS1026; + const double crLHS1042 = DN_v(9,2)*crLHS1026; + const double crLHS1043 = -DN_v(4,1)*N_p[0]; + const double crLHS1044 = -DN_v(4,1)*N_p[1]; + const double crLHS1045 = -DN_v(4,1)*N_p[2]; + const double crLHS1046 = -DN_v(4,1)*N_p[3]; + const double crLHS1047 = DN_v(4,2)*crLHS9; + const double crLHS1048 = DN_v(5,0)*crLHS1047; + const double crLHS1049 = DN_v(5,1)*crLHS1047; + const double crLHS1050 = DN_v(5,2)*crLHS1047; + const double crLHS1051 = DN_v(6,0)*crLHS1047; + const double crLHS1052 = DN_v(6,1)*crLHS1047; + const double crLHS1053 = DN_v(6,2)*crLHS1047; + const double crLHS1054 = DN_v(7,0)*crLHS1047; + const double crLHS1055 = DN_v(7,1)*crLHS1047; + const double crLHS1056 = DN_v(7,2)*crLHS1047; + const double crLHS1057 = DN_v(8,0)*crLHS1047; + const double crLHS1058 = DN_v(8,1)*crLHS1047; + const double crLHS1059 = DN_v(8,2)*crLHS1047; + const double crLHS1060 = DN_v(9,0)*crLHS1047; + const double crLHS1061 = DN_v(9,1)*crLHS1047; + const double crLHS1062 = DN_v(9,2)*crLHS1047; + const double crLHS1063 = -DN_v(4,2)*N_p[0]; + const double crLHS1064 = -DN_v(4,2)*N_p[1]; + const double crLHS1065 = -DN_v(4,2)*N_p[2]; + const double crLHS1066 = -DN_v(4,2)*N_p[3]; + const double crLHS1067 = crLHS181*crLHS20; + const double crLHS1068 = N_v[5]*crLHS22; + const double crLHS1069 = crLHS1068*crLHS20; + const double crLHS1070 = N_v[5]*crLHS15 + crLHS185; + const double crLHS1071 = N_v[5]*crLHS53 + crLHS707; + const double crLHS1072 = N_v[5]*crLHS85 + crLHS814; + const double crLHS1073 = N_v[5]*crLHS117 + crLHS911; + const double crLHS1074 = N_v[5]*crLHS149 + crLHS998; + const double crLHS1075 = std::pow(N_v[5], 2)*crLHS16 + N_v[5]*crLHS181; + const double crLHS1076 = DN_v(5,0)*crLHS9; + const double crLHS1077 = DN_v(5,1)*crLHS1076; + const double crLHS1078 = DN_v(5,2)*crLHS1076; + const double crLHS1079 = DN_v(6,0)*crLHS1076; + const double crLHS1080 = N_v[6]*crLHS182; + const double crLHS1081 = N_v[5]*crLHS213 + crLHS1080; + const double crLHS1082 = DN_v(6,1)*crLHS1076; + const double crLHS1083 = DN_v(6,2)*crLHS1076; + const double crLHS1084 = DN_v(7,0)*crLHS1076; + const double crLHS1085 = N_v[7]*crLHS182; + const double crLHS1086 = N_v[5]*crLHS245 + crLHS1085; + const double crLHS1087 = DN_v(7,1)*crLHS1076; + const double crLHS1088 = DN_v(7,2)*crLHS1076; + const double crLHS1089 = DN_v(8,0)*crLHS1076; + const double crLHS1090 = N_v[8]*crLHS182; + const double crLHS1091 = N_v[5]*crLHS277 + crLHS1090; + const double crLHS1092 = DN_v(8,1)*crLHS1076; + const double crLHS1093 = DN_v(8,2)*crLHS1076; + const double crLHS1094 = DN_v(9,0)*crLHS1076; + const double crLHS1095 = N_v[9]*crLHS182; + const double crLHS1096 = N_v[5]*crLHS309 + crLHS1095; + const double crLHS1097 = DN_v(9,1)*crLHS1076; + const double crLHS1098 = DN_v(9,2)*crLHS1076; + const double crLHS1099 = -DN_v(5,0)*N_p[0]; + const double crLHS1100 = -DN_v(5,0)*N_p[1]; + const double crLHS1101 = -DN_v(5,0)*N_p[2]; + const double crLHS1102 = -DN_v(5,0)*N_p[3]; + const double crLHS1103 = DN_v(5,1)*crLHS9; + const double crLHS1104 = DN_v(5,2)*crLHS1103; + const double crLHS1105 = DN_v(6,0)*crLHS1103; + const double crLHS1106 = DN_v(6,1)*crLHS1103; + const double crLHS1107 = DN_v(6,2)*crLHS1103; + const double crLHS1108 = DN_v(7,0)*crLHS1103; + const double crLHS1109 = DN_v(7,1)*crLHS1103; + const double crLHS1110 = DN_v(7,2)*crLHS1103; + const double crLHS1111 = DN_v(8,0)*crLHS1103; + const double crLHS1112 = DN_v(8,1)*crLHS1103; + const double crLHS1113 = DN_v(8,2)*crLHS1103; + const double crLHS1114 = DN_v(9,0)*crLHS1103; + const double crLHS1115 = DN_v(9,1)*crLHS1103; + const double crLHS1116 = DN_v(9,2)*crLHS1103; + const double crLHS1117 = -DN_v(5,1)*N_p[0]; + const double crLHS1118 = -DN_v(5,1)*N_p[1]; + const double crLHS1119 = -DN_v(5,1)*N_p[2]; + const double crLHS1120 = -DN_v(5,1)*N_p[3]; + const double crLHS1121 = DN_v(5,2)*crLHS9; + const double crLHS1122 = DN_v(6,0)*crLHS1121; + const double crLHS1123 = DN_v(6,1)*crLHS1121; + const double crLHS1124 = DN_v(6,2)*crLHS1121; + const double crLHS1125 = DN_v(7,0)*crLHS1121; + const double crLHS1126 = DN_v(7,1)*crLHS1121; + const double crLHS1127 = DN_v(7,2)*crLHS1121; + const double crLHS1128 = DN_v(8,0)*crLHS1121; + const double crLHS1129 = DN_v(8,1)*crLHS1121; + const double crLHS1130 = DN_v(8,2)*crLHS1121; + const double crLHS1131 = DN_v(9,0)*crLHS1121; + const double crLHS1132 = DN_v(9,1)*crLHS1121; + const double crLHS1133 = DN_v(9,2)*crLHS1121; + const double crLHS1134 = -DN_v(5,2)*N_p[0]; + const double crLHS1135 = -DN_v(5,2)*N_p[1]; + const double crLHS1136 = -DN_v(5,2)*N_p[2]; + const double crLHS1137 = -DN_v(5,2)*N_p[3]; + const double crLHS1138 = crLHS20*crLHS213; + const double crLHS1139 = N_v[6]*crLHS22; + const double crLHS1140 = crLHS1139*crLHS20; + const double crLHS1141 = N_v[6]*crLHS15 + crLHS217; + const double crLHS1142 = N_v[6]*crLHS53 + crLHS712; + const double crLHS1143 = N_v[6]*crLHS85 + crLHS819; + const double crLHS1144 = N_v[6]*crLHS117 + crLHS916; + const double crLHS1145 = N_v[6]*crLHS149 + crLHS1003; + const double crLHS1146 = N_v[6]*crLHS181 + crLHS1080; + const double crLHS1147 = std::pow(N_v[6], 2)*crLHS16 + N_v[6]*crLHS213; + const double crLHS1148 = DN_v(6,0)*crLHS9; + const double crLHS1149 = DN_v(6,1)*crLHS1148; + const double crLHS1150 = DN_v(6,2)*crLHS1148; + const double crLHS1151 = DN_v(7,0)*crLHS1148; + const double crLHS1152 = N_v[7]*crLHS214; + const double crLHS1153 = N_v[6]*crLHS245 + crLHS1152; + const double crLHS1154 = DN_v(7,1)*crLHS1148; + const double crLHS1155 = DN_v(7,2)*crLHS1148; + const double crLHS1156 = DN_v(8,0)*crLHS1148; + const double crLHS1157 = N_v[8]*crLHS214; + const double crLHS1158 = N_v[6]*crLHS277 + crLHS1157; + const double crLHS1159 = DN_v(8,1)*crLHS1148; + const double crLHS1160 = DN_v(8,2)*crLHS1148; + const double crLHS1161 = DN_v(9,0)*crLHS1148; + const double crLHS1162 = N_v[9]*crLHS214; + const double crLHS1163 = N_v[6]*crLHS309 + crLHS1162; + const double crLHS1164 = DN_v(9,1)*crLHS1148; + const double crLHS1165 = DN_v(9,2)*crLHS1148; + const double crLHS1166 = -DN_v(6,0)*N_p[0]; + const double crLHS1167 = -DN_v(6,0)*N_p[1]; + const double crLHS1168 = -DN_v(6,0)*N_p[2]; + const double crLHS1169 = -DN_v(6,0)*N_p[3]; + const double crLHS1170 = DN_v(6,1)*crLHS9; + const double crLHS1171 = DN_v(6,2)*crLHS1170; + const double crLHS1172 = DN_v(7,0)*crLHS1170; + const double crLHS1173 = DN_v(7,1)*crLHS1170; + const double crLHS1174 = DN_v(7,2)*crLHS1170; + const double crLHS1175 = DN_v(8,0)*crLHS1170; + const double crLHS1176 = DN_v(8,1)*crLHS1170; + const double crLHS1177 = DN_v(8,2)*crLHS1170; + const double crLHS1178 = DN_v(9,0)*crLHS1170; + const double crLHS1179 = DN_v(9,1)*crLHS1170; + const double crLHS1180 = DN_v(9,2)*crLHS1170; + const double crLHS1181 = -DN_v(6,1)*N_p[0]; + const double crLHS1182 = -DN_v(6,1)*N_p[1]; + const double crLHS1183 = -DN_v(6,1)*N_p[2]; + const double crLHS1184 = -DN_v(6,1)*N_p[3]; + const double crLHS1185 = DN_v(6,2)*crLHS9; + const double crLHS1186 = DN_v(7,0)*crLHS1185; + const double crLHS1187 = DN_v(7,1)*crLHS1185; + const double crLHS1188 = DN_v(7,2)*crLHS1185; + const double crLHS1189 = DN_v(8,0)*crLHS1185; + const double crLHS1190 = DN_v(8,1)*crLHS1185; + const double crLHS1191 = DN_v(8,2)*crLHS1185; + const double crLHS1192 = DN_v(9,0)*crLHS1185; + const double crLHS1193 = DN_v(9,1)*crLHS1185; + const double crLHS1194 = DN_v(9,2)*crLHS1185; + const double crLHS1195 = -DN_v(6,2)*N_p[0]; + const double crLHS1196 = -DN_v(6,2)*N_p[1]; + const double crLHS1197 = -DN_v(6,2)*N_p[2]; + const double crLHS1198 = -DN_v(6,2)*N_p[3]; + const double crLHS1199 = crLHS20*crLHS245; + const double crLHS1200 = N_v[7]*crLHS22; + const double crLHS1201 = crLHS1200*crLHS20; + const double crLHS1202 = N_v[7]*crLHS15 + crLHS249; + const double crLHS1203 = N_v[7]*crLHS53 + crLHS717; + const double crLHS1204 = N_v[7]*crLHS85 + crLHS824; + const double crLHS1205 = N_v[7]*crLHS117 + crLHS921; + const double crLHS1206 = N_v[7]*crLHS149 + crLHS1008; + const double crLHS1207 = N_v[7]*crLHS181 + crLHS1085; + const double crLHS1208 = N_v[7]*crLHS213 + crLHS1152; + const double crLHS1209 = std::pow(N_v[7], 2)*crLHS16 + N_v[7]*crLHS245; + const double crLHS1210 = DN_v(7,0)*crLHS9; + const double crLHS1211 = DN_v(7,1)*crLHS1210; + const double crLHS1212 = DN_v(7,2)*crLHS1210; + const double crLHS1213 = DN_v(8,0)*crLHS1210; + const double crLHS1214 = N_v[8]*crLHS246; + const double crLHS1215 = N_v[7]*crLHS277 + crLHS1214; + const double crLHS1216 = DN_v(8,1)*crLHS1210; + const double crLHS1217 = DN_v(8,2)*crLHS1210; + const double crLHS1218 = DN_v(9,0)*crLHS1210; + const double crLHS1219 = N_v[9]*crLHS246; + const double crLHS1220 = N_v[7]*crLHS309 + crLHS1219; + const double crLHS1221 = DN_v(9,1)*crLHS1210; + const double crLHS1222 = DN_v(9,2)*crLHS1210; + const double crLHS1223 = -DN_v(7,0)*N_p[0]; + const double crLHS1224 = -DN_v(7,0)*N_p[1]; + const double crLHS1225 = -DN_v(7,0)*N_p[2]; + const double crLHS1226 = -DN_v(7,0)*N_p[3]; + const double crLHS1227 = DN_v(7,1)*crLHS9; + const double crLHS1228 = DN_v(7,2)*crLHS1227; + const double crLHS1229 = DN_v(8,0)*crLHS1227; + const double crLHS1230 = DN_v(8,1)*crLHS1227; + const double crLHS1231 = DN_v(8,2)*crLHS1227; + const double crLHS1232 = DN_v(9,0)*crLHS1227; + const double crLHS1233 = DN_v(9,1)*crLHS1227; + const double crLHS1234 = DN_v(9,2)*crLHS1227; + const double crLHS1235 = -DN_v(7,1)*N_p[0]; + const double crLHS1236 = -DN_v(7,1)*N_p[1]; + const double crLHS1237 = -DN_v(7,1)*N_p[2]; + const double crLHS1238 = -DN_v(7,1)*N_p[3]; + const double crLHS1239 = DN_v(7,2)*crLHS9; + const double crLHS1240 = DN_v(8,0)*crLHS1239; + const double crLHS1241 = DN_v(8,1)*crLHS1239; + const double crLHS1242 = DN_v(8,2)*crLHS1239; + const double crLHS1243 = DN_v(9,0)*crLHS1239; + const double crLHS1244 = DN_v(9,1)*crLHS1239; + const double crLHS1245 = DN_v(9,2)*crLHS1239; + const double crLHS1246 = -DN_v(7,2)*N_p[0]; + const double crLHS1247 = -DN_v(7,2)*N_p[1]; + const double crLHS1248 = -DN_v(7,2)*N_p[2]; + const double crLHS1249 = -DN_v(7,2)*N_p[3]; + const double crLHS1250 = crLHS20*crLHS277; + const double crLHS1251 = N_v[8]*crLHS22; + const double crLHS1252 = crLHS1251*crLHS20; + const double crLHS1253 = N_v[8]*crLHS15 + crLHS281; + const double crLHS1254 = N_v[8]*crLHS53 + crLHS722; + const double crLHS1255 = N_v[8]*crLHS85 + crLHS829; + const double crLHS1256 = N_v[8]*crLHS117 + crLHS926; + const double crLHS1257 = N_v[8]*crLHS149 + crLHS1013; + const double crLHS1258 = N_v[8]*crLHS181 + crLHS1090; + const double crLHS1259 = N_v[8]*crLHS213 + crLHS1157; + const double crLHS1260 = N_v[8]*crLHS245 + crLHS1214; + const double crLHS1261 = std::pow(N_v[8], 2)*crLHS16 + N_v[8]*crLHS277; + const double crLHS1262 = DN_v(8,0)*crLHS9; + const double crLHS1263 = DN_v(8,1)*crLHS1262; + const double crLHS1264 = DN_v(8,2)*crLHS1262; + const double crLHS1265 = DN_v(9,0)*crLHS1262; + const double crLHS1266 = N_v[9]*crLHS278; + const double crLHS1267 = N_v[8]*crLHS309 + crLHS1266; + const double crLHS1268 = DN_v(9,1)*crLHS1262; + const double crLHS1269 = DN_v(9,2)*crLHS1262; + const double crLHS1270 = -DN_v(8,0)*N_p[0]; + const double crLHS1271 = -DN_v(8,0)*N_p[1]; + const double crLHS1272 = -DN_v(8,0)*N_p[2]; + const double crLHS1273 = -DN_v(8,0)*N_p[3]; + const double crLHS1274 = DN_v(8,1)*crLHS9; + const double crLHS1275 = DN_v(8,2)*crLHS1274; + const double crLHS1276 = DN_v(9,0)*crLHS1274; + const double crLHS1277 = DN_v(9,1)*crLHS1274; + const double crLHS1278 = DN_v(9,2)*crLHS1274; + const double crLHS1279 = -DN_v(8,1)*N_p[0]; + const double crLHS1280 = -DN_v(8,1)*N_p[1]; + const double crLHS1281 = -DN_v(8,1)*N_p[2]; + const double crLHS1282 = -DN_v(8,1)*N_p[3]; + const double crLHS1283 = DN_v(8,2)*crLHS9; + const double crLHS1284 = DN_v(9,0)*crLHS1283; + const double crLHS1285 = DN_v(9,1)*crLHS1283; + const double crLHS1286 = DN_v(9,2)*crLHS1283; + const double crLHS1287 = -DN_v(8,2)*N_p[0]; + const double crLHS1288 = -DN_v(8,2)*N_p[1]; + const double crLHS1289 = -DN_v(8,2)*N_p[2]; + const double crLHS1290 = -DN_v(8,2)*N_p[3]; + const double crLHS1291 = crLHS20*crLHS309; + const double crLHS1292 = N_v[9]*crLHS22; + const double crLHS1293 = crLHS1292*crLHS20; + const double crLHS1294 = N_v[9]*crLHS15 + crLHS312; + const double crLHS1295 = N_v[9]*crLHS53 + crLHS727; + const double crLHS1296 = N_v[9]*crLHS85 + crLHS834; + const double crLHS1297 = N_v[9]*crLHS117 + crLHS931; + const double crLHS1298 = N_v[9]*crLHS149 + crLHS1018; + const double crLHS1299 = N_v[9]*crLHS181 + crLHS1095; + const double crLHS1300 = N_v[9]*crLHS213 + crLHS1162; + const double crLHS1301 = N_v[9]*crLHS245 + crLHS1219; + const double crLHS1302 = N_v[9]*crLHS277 + crLHS1266; + const double crLHS1303 = std::pow(N_v[9], 2)*crLHS16 + N_v[9]*crLHS309; + const double crLHS1304 = DN_v(9,0)*crLHS9; + const double crLHS1305 = DN_v(9,1)*crLHS1304; + const double crLHS1306 = DN_v(9,2)*crLHS1304; + const double crLHS1307 = -DN_v(9,0)*N_p[0]; + const double crLHS1308 = -DN_v(9,0)*N_p[1]; + const double crLHS1309 = -DN_v(9,0)*N_p[2]; + const double crLHS1310 = -DN_v(9,0)*N_p[3]; + const double crLHS1311 = DN_v(9,1)*DN_v(9,2)*crLHS9; + const double crLHS1312 = -DN_v(9,1)*N_p[0]; + const double crLHS1313 = -DN_v(9,1)*N_p[1]; + const double crLHS1314 = -DN_v(9,1)*N_p[2]; + const double crLHS1315 = -DN_v(9,1)*N_p[3]; + const double crLHS1316 = -DN_v(9,2)*N_p[0]; + const double crLHS1317 = -DN_v(9,2)*N_p[1]; + const double crLHS1318 = -DN_v(9,2)*N_p[2]; + const double crLHS1319 = -DN_v(9,2)*N_p[3]; + const double crLHS1320 = crLHS20*gauss_weight; + const double crLHS1321 = crLHS1320*(DN_p(0,0)*DN_p(1,0) + DN_p(0,1)*DN_p(1,1) + DN_p(0,2)*DN_p(1,2)); + const double crLHS1322 = crLHS1320*(DN_p(0,0)*DN_p(2,0) + DN_p(0,1)*DN_p(2,1) + DN_p(0,2)*DN_p(2,2)); + const double crLHS1323 = crLHS1320*(DN_p(0,0)*DN_p(3,0) + DN_p(0,1)*DN_p(3,1) + DN_p(0,2)*DN_p(3,2)); + const double crLHS1324 = crLHS1320*(DN_p(1,0)*DN_p(2,0) + DN_p(1,1)*DN_p(2,1) + DN_p(1,2)*DN_p(2,2)); + const double crLHS1325 = crLHS1320*(DN_p(1,0)*DN_p(3,0) + DN_p(1,1)*DN_p(3,1) + DN_p(1,2)*DN_p(3,2)); + const double crLHS1326 = crLHS1320*(DN_p(2,0)*DN_p(3,0) + DN_p(2,1)*DN_p(3,1) + DN_p(2,2)*DN_p(3,2)); + rLHS(0,0)+=gauss_weight*(std::pow(DN_v(0,0), 2)*crLHS9 + DN_v(0,0)*crLHS0 + DN_v(0,1)*crLHS2 + DN_v(0,2)*crLHS4 - crLHS19*crLHS21 - crLHS19*crLHS24 + crLHS25); + rLHS(0,1)+=gauss_weight*(DN_v(0,0)*crLHS26 + DN_v(0,1)*crLHS28 + DN_v(0,2)*crLHS31 - crLHS21*crLHS35 - crLHS24*crLHS35 + crLHS33); + rLHS(0,2)+=gauss_weight*(DN_v(0,0)*crLHS36 + DN_v(0,1)*crLHS38 + DN_v(0,2)*crLHS40 - crLHS21*crLHS42 - crLHS24*crLHS42 + crLHS41); + rLHS(0,3)+=gauss_weight*(DN_v(0,0)*crLHS43 + DN_v(0,1)*crLHS45 + DN_v(0,2)*crLHS47 - crLHS21*crLHS56 - crLHS24*crLHS56 + crLHS48 + crLHS58); + rLHS(0,4)+=gauss_weight*(DN_v(0,0)*crLHS59 + DN_v(0,1)*crLHS61 + DN_v(0,2)*crLHS64 - crLHS21*crLHS67 - crLHS24*crLHS67 + crLHS65); + rLHS(0,5)+=gauss_weight*(DN_v(0,0)*crLHS68 + DN_v(0,1)*crLHS70 + DN_v(0,2)*crLHS72 - crLHS21*crLHS74 - crLHS24*crLHS74 + crLHS73); + rLHS(0,6)+=gauss_weight*(DN_v(0,0)*crLHS75 + DN_v(0,1)*crLHS77 + DN_v(0,2)*crLHS79 - crLHS21*crLHS88 - crLHS24*crLHS88 + crLHS80 + crLHS90); + rLHS(0,7)+=gauss_weight*(DN_v(0,0)*crLHS91 + DN_v(0,1)*crLHS93 + DN_v(0,2)*crLHS96 - crLHS21*crLHS99 - crLHS24*crLHS99 + crLHS97); + rLHS(0,8)+=gauss_weight*(DN_v(0,0)*crLHS100 + DN_v(0,1)*crLHS102 + DN_v(0,2)*crLHS104 + crLHS105 - crLHS106*crLHS21 - crLHS106*crLHS24); + rLHS(0,9)+=gauss_weight*(DN_v(0,0)*crLHS107 + DN_v(0,1)*crLHS109 + DN_v(0,2)*crLHS111 + crLHS112 - crLHS120*crLHS21 - crLHS120*crLHS24 + crLHS122); + rLHS(0,10)+=gauss_weight*(DN_v(0,0)*crLHS123 + DN_v(0,1)*crLHS125 + DN_v(0,2)*crLHS128 + crLHS129 - crLHS131*crLHS21 - crLHS131*crLHS24); + rLHS(0,11)+=gauss_weight*(DN_v(0,0)*crLHS132 + DN_v(0,1)*crLHS134 + DN_v(0,2)*crLHS136 + crLHS137 - crLHS138*crLHS21 - crLHS138*crLHS24); + rLHS(0,12)+=gauss_weight*(DN_v(0,0)*crLHS139 + DN_v(0,1)*crLHS141 + DN_v(0,2)*crLHS143 + crLHS144 - crLHS152*crLHS21 - crLHS152*crLHS24 + crLHS154); + rLHS(0,13)+=gauss_weight*(DN_v(0,0)*crLHS155 + DN_v(0,1)*crLHS157 + DN_v(0,2)*crLHS160 + crLHS161 - crLHS163*crLHS21 - crLHS163*crLHS24); + rLHS(0,14)+=gauss_weight*(DN_v(0,0)*crLHS164 + DN_v(0,1)*crLHS166 + DN_v(0,2)*crLHS168 + crLHS169 - crLHS170*crLHS21 - crLHS170*crLHS24); + rLHS(0,15)+=gauss_weight*(DN_v(0,0)*crLHS171 + DN_v(0,1)*crLHS173 + DN_v(0,2)*crLHS175 + crLHS176 - crLHS184*crLHS21 - crLHS184*crLHS24 + crLHS186); + rLHS(0,16)+=gauss_weight*(DN_v(0,0)*crLHS187 + DN_v(0,1)*crLHS189 + DN_v(0,2)*crLHS192 + crLHS193 - crLHS195*crLHS21 - crLHS195*crLHS24); + rLHS(0,17)+=gauss_weight*(DN_v(0,0)*crLHS196 + DN_v(0,1)*crLHS198 + DN_v(0,2)*crLHS200 + crLHS201 - crLHS202*crLHS21 - crLHS202*crLHS24); + rLHS(0,18)+=gauss_weight*(DN_v(0,0)*crLHS203 + DN_v(0,1)*crLHS205 + DN_v(0,2)*crLHS207 + crLHS208 - crLHS21*crLHS216 - crLHS216*crLHS24 + crLHS218); + rLHS(0,19)+=gauss_weight*(DN_v(0,0)*crLHS219 + DN_v(0,1)*crLHS221 + DN_v(0,2)*crLHS224 - crLHS21*crLHS227 + crLHS225 - crLHS227*crLHS24); + rLHS(0,20)+=gauss_weight*(DN_v(0,0)*crLHS228 + DN_v(0,1)*crLHS230 + DN_v(0,2)*crLHS232 - crLHS21*crLHS234 + crLHS233 - crLHS234*crLHS24); + rLHS(0,21)+=gauss_weight*(DN_v(0,0)*crLHS235 + DN_v(0,1)*crLHS237 + DN_v(0,2)*crLHS239 - crLHS21*crLHS248 - crLHS24*crLHS248 + crLHS240 + crLHS250); + rLHS(0,22)+=gauss_weight*(DN_v(0,0)*crLHS251 + DN_v(0,1)*crLHS253 + DN_v(0,2)*crLHS256 - crLHS21*crLHS259 - crLHS24*crLHS259 + crLHS257); + rLHS(0,23)+=gauss_weight*(DN_v(0,0)*crLHS260 + DN_v(0,1)*crLHS262 + DN_v(0,2)*crLHS264 - crLHS21*crLHS266 - crLHS24*crLHS266 + crLHS265); + rLHS(0,24)+=gauss_weight*(DN_v(0,0)*crLHS267 + DN_v(0,1)*crLHS269 + DN_v(0,2)*crLHS271 - crLHS21*crLHS280 - crLHS24*crLHS280 + crLHS272 + crLHS282); + rLHS(0,25)+=gauss_weight*(DN_v(0,0)*crLHS283 + DN_v(0,1)*crLHS285 + DN_v(0,2)*crLHS288 - crLHS21*crLHS291 - crLHS24*crLHS291 + crLHS289); + rLHS(0,26)+=gauss_weight*(DN_v(0,0)*crLHS292 + DN_v(0,1)*crLHS294 + DN_v(0,2)*crLHS296 - crLHS21*crLHS298 - crLHS24*crLHS298 + crLHS297); + rLHS(0,27)+=gauss_weight*(DN_v(0,0)*crLHS299 + DN_v(0,1)*crLHS301 + DN_v(0,2)*crLHS303 - crLHS21*crLHS311 - crLHS24*crLHS311 + crLHS304 + crLHS313); + rLHS(0,28)+=gauss_weight*(DN_v(0,0)*crLHS314 + DN_v(0,1)*crLHS316 + DN_v(0,2)*crLHS319 - crLHS21*crLHS322 - crLHS24*crLHS322 + crLHS320); + rLHS(0,29)+=gauss_weight*(DN_v(0,0)*crLHS323 + DN_v(0,1)*crLHS325 + DN_v(0,2)*crLHS327 - crLHS21*crLHS329 - crLHS24*crLHS329 + crLHS328); + rLHS(0,30)+=gauss_weight*(crLHS15*crLHS331 + crLHS23*crLHS331 + crLHS330); + rLHS(0,31)+=gauss_weight*(crLHS15*crLHS333 + crLHS23*crLHS333 + crLHS332); + rLHS(0,32)+=gauss_weight*(crLHS15*crLHS335 + crLHS23*crLHS335 + crLHS334); + rLHS(0,33)+=gauss_weight*(crLHS15*crLHS337 + crLHS23*crLHS337 + crLHS336); + rLHS(1,0)+=gauss_weight*(DN_v(0,0)*crLHS2 + DN_v(0,1)*crLHS338 + DN_v(0,2)*crLHS339 - crLHS21*crLHS342 - crLHS24*crLHS342 + crLHS33); + rLHS(1,1)+=gauss_weight*(DN_v(0,0)*crLHS28 + std::pow(DN_v(0,1), 2)*crLHS9 + DN_v(0,1)*crLHS343 + DN_v(0,2)*crLHS345 - crLHS21*crLHS350 - crLHS24*crLHS350 + crLHS25); + rLHS(1,2)+=gauss_weight*(DN_v(0,0)*crLHS38 + DN_v(0,1)*crLHS351 + DN_v(0,2)*crLHS353 - crLHS21*crLHS356 - crLHS24*crLHS356 + crLHS355); + rLHS(1,3)+=gauss_weight*(DN_v(0,0)*crLHS45 + DN_v(0,1)*crLHS357 + DN_v(0,2)*crLHS358 - crLHS21*crLHS362 - crLHS24*crLHS362 + crLHS359); + rLHS(1,4)+=gauss_weight*(DN_v(0,0)*crLHS61 + DN_v(0,1)*crLHS363 + DN_v(0,2)*crLHS365 - crLHS21*crLHS370 - crLHS24*crLHS370 + crLHS366 + crLHS58); + rLHS(1,5)+=gauss_weight*(DN_v(0,0)*crLHS70 + DN_v(0,1)*crLHS371 + DN_v(0,2)*crLHS373 - crLHS21*crLHS375 - crLHS24*crLHS375 + crLHS374); + rLHS(1,6)+=gauss_weight*(DN_v(0,0)*crLHS77 + DN_v(0,1)*crLHS376 + DN_v(0,2)*crLHS377 - crLHS21*crLHS381 - crLHS24*crLHS381 + crLHS378); + rLHS(1,7)+=gauss_weight*(DN_v(0,0)*crLHS93 + DN_v(0,1)*crLHS382 + DN_v(0,2)*crLHS384 - crLHS21*crLHS389 - crLHS24*crLHS389 + crLHS385 + crLHS90); + rLHS(1,8)+=gauss_weight*(DN_v(0,0)*crLHS102 + DN_v(0,1)*crLHS390 + DN_v(0,2)*crLHS392 - crLHS21*crLHS394 - crLHS24*crLHS394 + crLHS393); + rLHS(1,9)+=gauss_weight*(DN_v(0,0)*crLHS109 + DN_v(0,1)*crLHS395 + DN_v(0,2)*crLHS396 - crLHS21*crLHS400 - crLHS24*crLHS400 + crLHS397); + rLHS(1,10)+=gauss_weight*(DN_v(0,0)*crLHS125 + DN_v(0,1)*crLHS401 + DN_v(0,2)*crLHS403 + crLHS122 - crLHS21*crLHS408 - crLHS24*crLHS408 + crLHS404); + rLHS(1,11)+=gauss_weight*(DN_v(0,0)*crLHS134 + DN_v(0,1)*crLHS409 + DN_v(0,2)*crLHS411 - crLHS21*crLHS413 - crLHS24*crLHS413 + crLHS412); + rLHS(1,12)+=gauss_weight*(DN_v(0,0)*crLHS141 + DN_v(0,1)*crLHS414 + DN_v(0,2)*crLHS415 - crLHS21*crLHS419 - crLHS24*crLHS419 + crLHS416); + rLHS(1,13)+=gauss_weight*(DN_v(0,0)*crLHS157 + DN_v(0,1)*crLHS420 + DN_v(0,2)*crLHS422 + crLHS154 - crLHS21*crLHS427 - crLHS24*crLHS427 + crLHS423); + rLHS(1,14)+=gauss_weight*(DN_v(0,0)*crLHS166 + DN_v(0,1)*crLHS428 + DN_v(0,2)*crLHS430 - crLHS21*crLHS432 - crLHS24*crLHS432 + crLHS431); + rLHS(1,15)+=gauss_weight*(DN_v(0,0)*crLHS173 + DN_v(0,1)*crLHS433 + DN_v(0,2)*crLHS434 - crLHS21*crLHS438 - crLHS24*crLHS438 + crLHS435); + rLHS(1,16)+=gauss_weight*(DN_v(0,0)*crLHS189 + DN_v(0,1)*crLHS439 + DN_v(0,2)*crLHS441 + crLHS186 - crLHS21*crLHS446 - crLHS24*crLHS446 + crLHS442); + rLHS(1,17)+=gauss_weight*(DN_v(0,0)*crLHS198 + DN_v(0,1)*crLHS447 + DN_v(0,2)*crLHS449 - crLHS21*crLHS451 - crLHS24*crLHS451 + crLHS450); + rLHS(1,18)+=gauss_weight*(DN_v(0,0)*crLHS205 + DN_v(0,1)*crLHS452 + DN_v(0,2)*crLHS453 - crLHS21*crLHS457 - crLHS24*crLHS457 + crLHS454); + rLHS(1,19)+=gauss_weight*(DN_v(0,0)*crLHS221 + DN_v(0,1)*crLHS458 + DN_v(0,2)*crLHS460 - crLHS21*crLHS465 + crLHS218 - crLHS24*crLHS465 + crLHS461); + rLHS(1,20)+=gauss_weight*(DN_v(0,0)*crLHS230 + DN_v(0,1)*crLHS466 + DN_v(0,2)*crLHS468 - crLHS21*crLHS470 - crLHS24*crLHS470 + crLHS469); + rLHS(1,21)+=gauss_weight*(DN_v(0,0)*crLHS237 + DN_v(0,1)*crLHS471 + DN_v(0,2)*crLHS472 - crLHS21*crLHS476 - crLHS24*crLHS476 + crLHS473); + rLHS(1,22)+=gauss_weight*(DN_v(0,0)*crLHS253 + DN_v(0,1)*crLHS477 + DN_v(0,2)*crLHS479 - crLHS21*crLHS484 - crLHS24*crLHS484 + crLHS250 + crLHS480); + rLHS(1,23)+=gauss_weight*(DN_v(0,0)*crLHS262 + DN_v(0,1)*crLHS485 + DN_v(0,2)*crLHS487 - crLHS21*crLHS489 - crLHS24*crLHS489 + crLHS488); + rLHS(1,24)+=gauss_weight*(DN_v(0,0)*crLHS269 + DN_v(0,1)*crLHS490 + DN_v(0,2)*crLHS491 - crLHS21*crLHS495 - crLHS24*crLHS495 + crLHS492); + rLHS(1,25)+=gauss_weight*(DN_v(0,0)*crLHS285 + DN_v(0,1)*crLHS496 + DN_v(0,2)*crLHS498 - crLHS21*crLHS503 - crLHS24*crLHS503 + crLHS282 + crLHS499); + rLHS(1,26)+=gauss_weight*(DN_v(0,0)*crLHS294 + DN_v(0,1)*crLHS504 + DN_v(0,2)*crLHS506 - crLHS21*crLHS508 - crLHS24*crLHS508 + crLHS507); + rLHS(1,27)+=gauss_weight*(DN_v(0,0)*crLHS301 + DN_v(0,1)*crLHS509 + DN_v(0,2)*crLHS510 - crLHS21*crLHS514 - crLHS24*crLHS514 + crLHS511); + rLHS(1,28)+=gauss_weight*(DN_v(0,0)*crLHS316 + DN_v(0,1)*crLHS515 + DN_v(0,2)*crLHS517 - crLHS21*crLHS522 - crLHS24*crLHS522 + crLHS313 + crLHS518); + rLHS(1,29)+=gauss_weight*(DN_v(0,0)*crLHS325 + DN_v(0,1)*crLHS523 + DN_v(0,2)*crLHS525 - crLHS21*crLHS527 - crLHS24*crLHS527 + crLHS526); + rLHS(1,30)+=gauss_weight*(crLHS15*crLHS529 + crLHS23*crLHS529 + crLHS528); + rLHS(1,31)+=gauss_weight*(crLHS15*crLHS531 + crLHS23*crLHS531 + crLHS530); + rLHS(1,32)+=gauss_weight*(crLHS15*crLHS533 + crLHS23*crLHS533 + crLHS532); + rLHS(1,33)+=gauss_weight*(crLHS15*crLHS535 + crLHS23*crLHS535 + crLHS534); + rLHS(2,0)+=gauss_weight*(DN_v(0,0)*crLHS4 + DN_v(0,1)*crLHS339 + DN_v(0,2)*crLHS536 - crLHS21*crLHS539 - crLHS24*crLHS539 + crLHS41); + rLHS(2,1)+=gauss_weight*(DN_v(0,0)*crLHS31 + DN_v(0,1)*crLHS345 + DN_v(0,2)*crLHS540 - crLHS21*crLHS542 - crLHS24*crLHS542 + crLHS355); + rLHS(2,2)+=gauss_weight*(DN_v(0,0)*crLHS40 + DN_v(0,1)*crLHS353 + std::pow(DN_v(0,2), 2)*crLHS9 + DN_v(0,2)*crLHS543 - crLHS21*crLHS547 - crLHS24*crLHS547 + crLHS25); + rLHS(2,3)+=gauss_weight*(DN_v(0,0)*crLHS47 + DN_v(0,1)*crLHS358 + DN_v(0,2)*crLHS548 - crLHS21*crLHS553 - crLHS24*crLHS553 + crLHS550); + rLHS(2,4)+=gauss_weight*(DN_v(0,0)*crLHS64 + DN_v(0,1)*crLHS365 + DN_v(0,2)*crLHS554 - crLHS21*crLHS557 - crLHS24*crLHS557 + crLHS555); + rLHS(2,5)+=gauss_weight*(DN_v(0,0)*crLHS72 + DN_v(0,1)*crLHS373 + DN_v(0,2)*crLHS558 - crLHS21*crLHS562 - crLHS24*crLHS562 + crLHS559 + crLHS58); + rLHS(2,6)+=gauss_weight*(DN_v(0,0)*crLHS79 + DN_v(0,1)*crLHS377 + DN_v(0,2)*crLHS563 - crLHS21*crLHS567 - crLHS24*crLHS567 + crLHS564); + rLHS(2,7)+=gauss_weight*(DN_v(0,0)*crLHS96 + DN_v(0,1)*crLHS384 + DN_v(0,2)*crLHS568 - crLHS21*crLHS571 - crLHS24*crLHS571 + crLHS569); + rLHS(2,8)+=gauss_weight*(DN_v(0,0)*crLHS104 + DN_v(0,1)*crLHS392 + DN_v(0,2)*crLHS572 - crLHS21*crLHS576 - crLHS24*crLHS576 + crLHS573 + crLHS90); + rLHS(2,9)+=gauss_weight*(DN_v(0,0)*crLHS111 + DN_v(0,1)*crLHS396 + DN_v(0,2)*crLHS577 - crLHS21*crLHS581 - crLHS24*crLHS581 + crLHS578); + rLHS(2,10)+=gauss_weight*(DN_v(0,0)*crLHS128 + DN_v(0,1)*crLHS403 + DN_v(0,2)*crLHS582 - crLHS21*crLHS585 - crLHS24*crLHS585 + crLHS583); + rLHS(2,11)+=gauss_weight*(DN_v(0,0)*crLHS136 + DN_v(0,1)*crLHS411 + DN_v(0,2)*crLHS586 + crLHS122 - crLHS21*crLHS590 - crLHS24*crLHS590 + crLHS587); + rLHS(2,12)+=gauss_weight*(DN_v(0,0)*crLHS143 + DN_v(0,1)*crLHS415 + DN_v(0,2)*crLHS591 - crLHS21*crLHS595 - crLHS24*crLHS595 + crLHS592); + rLHS(2,13)+=gauss_weight*(DN_v(0,0)*crLHS160 + DN_v(0,1)*crLHS422 + DN_v(0,2)*crLHS596 - crLHS21*crLHS599 - crLHS24*crLHS599 + crLHS597); + rLHS(2,14)+=gauss_weight*(DN_v(0,0)*crLHS168 + DN_v(0,1)*crLHS430 + DN_v(0,2)*crLHS600 + crLHS154 - crLHS21*crLHS604 - crLHS24*crLHS604 + crLHS601); + rLHS(2,15)+=gauss_weight*(DN_v(0,0)*crLHS175 + DN_v(0,1)*crLHS434 + DN_v(0,2)*crLHS605 - crLHS21*crLHS609 - crLHS24*crLHS609 + crLHS606); + rLHS(2,16)+=gauss_weight*(DN_v(0,0)*crLHS192 + DN_v(0,1)*crLHS441 + DN_v(0,2)*crLHS610 - crLHS21*crLHS613 - crLHS24*crLHS613 + crLHS611); + rLHS(2,17)+=gauss_weight*(DN_v(0,0)*crLHS200 + DN_v(0,1)*crLHS449 + DN_v(0,2)*crLHS614 + crLHS186 - crLHS21*crLHS618 - crLHS24*crLHS618 + crLHS615); + rLHS(2,18)+=gauss_weight*(DN_v(0,0)*crLHS207 + DN_v(0,1)*crLHS453 + DN_v(0,2)*crLHS619 - crLHS21*crLHS623 - crLHS24*crLHS623 + crLHS620); + rLHS(2,19)+=gauss_weight*(DN_v(0,0)*crLHS224 + DN_v(0,1)*crLHS460 + DN_v(0,2)*crLHS624 - crLHS21*crLHS627 - crLHS24*crLHS627 + crLHS625); + rLHS(2,20)+=gauss_weight*(DN_v(0,0)*crLHS232 + DN_v(0,1)*crLHS468 + DN_v(0,2)*crLHS628 - crLHS21*crLHS632 + crLHS218 - crLHS24*crLHS632 + crLHS629); + rLHS(2,21)+=gauss_weight*(DN_v(0,0)*crLHS239 + DN_v(0,1)*crLHS472 + DN_v(0,2)*crLHS633 - crLHS21*crLHS637 - crLHS24*crLHS637 + crLHS634); + rLHS(2,22)+=gauss_weight*(DN_v(0,0)*crLHS256 + DN_v(0,1)*crLHS479 + DN_v(0,2)*crLHS638 - crLHS21*crLHS641 - crLHS24*crLHS641 + crLHS639); + rLHS(2,23)+=gauss_weight*(DN_v(0,0)*crLHS264 + DN_v(0,1)*crLHS487 + DN_v(0,2)*crLHS642 - crLHS21*crLHS646 - crLHS24*crLHS646 + crLHS250 + crLHS643); + rLHS(2,24)+=gauss_weight*(DN_v(0,0)*crLHS271 + DN_v(0,1)*crLHS491 + DN_v(0,2)*crLHS647 - crLHS21*crLHS651 - crLHS24*crLHS651 + crLHS648); + rLHS(2,25)+=gauss_weight*(DN_v(0,0)*crLHS288 + DN_v(0,1)*crLHS498 + DN_v(0,2)*crLHS652 - crLHS21*crLHS655 - crLHS24*crLHS655 + crLHS653); + rLHS(2,26)+=gauss_weight*(DN_v(0,0)*crLHS296 + DN_v(0,1)*crLHS506 + DN_v(0,2)*crLHS656 - crLHS21*crLHS660 - crLHS24*crLHS660 + crLHS282 + crLHS657); + rLHS(2,27)+=gauss_weight*(DN_v(0,0)*crLHS303 + DN_v(0,1)*crLHS510 + DN_v(0,2)*crLHS661 - crLHS21*crLHS665 - crLHS24*crLHS665 + crLHS662); + rLHS(2,28)+=gauss_weight*(DN_v(0,0)*crLHS319 + DN_v(0,1)*crLHS517 + DN_v(0,2)*crLHS666 - crLHS21*crLHS669 - crLHS24*crLHS669 + crLHS667); + rLHS(2,29)+=gauss_weight*(DN_v(0,0)*crLHS327 + DN_v(0,1)*crLHS525 + DN_v(0,2)*crLHS670 - crLHS21*crLHS674 - crLHS24*crLHS674 + crLHS313 + crLHS671); + rLHS(2,30)+=gauss_weight*(crLHS15*crLHS676 + crLHS23*crLHS676 + crLHS675); + rLHS(2,31)+=gauss_weight*(crLHS15*crLHS678 + crLHS23*crLHS678 + crLHS677); + rLHS(2,32)+=gauss_weight*(crLHS15*crLHS680 + crLHS23*crLHS680 + crLHS679); + rLHS(2,33)+=gauss_weight*(crLHS15*crLHS682 + crLHS23*crLHS682 + crLHS681); + rLHS(3,0)+=gauss_weight*(DN_v(1,0)*crLHS0 + DN_v(1,1)*crLHS2 + DN_v(1,2)*crLHS4 - crLHS19*crLHS683 - crLHS19*crLHS685 + crLHS48 + crLHS686); + rLHS(3,1)+=gauss_weight*(DN_v(1,0)*crLHS26 + DN_v(1,1)*crLHS28 + DN_v(1,2)*crLHS31 - crLHS35*crLHS683 - crLHS35*crLHS685 + crLHS359); + rLHS(3,2)+=gauss_weight*(DN_v(1,0)*crLHS36 + DN_v(1,1)*crLHS38 + DN_v(1,2)*crLHS40 - crLHS42*crLHS683 - crLHS42*crLHS685 + crLHS550); + rLHS(3,3)+=gauss_weight*(std::pow(DN_v(1,0), 2)*crLHS9 + DN_v(1,0)*crLHS43 + DN_v(1,1)*crLHS45 + DN_v(1,2)*crLHS47 - crLHS56*crLHS683 - crLHS56*crLHS685 + crLHS687); + rLHS(3,4)+=gauss_weight*(DN_v(1,0)*crLHS59 + DN_v(1,1)*crLHS61 + DN_v(1,2)*crLHS64 - crLHS67*crLHS683 - crLHS67*crLHS685 + crLHS689); + rLHS(3,5)+=gauss_weight*(DN_v(1,0)*crLHS68 + DN_v(1,1)*crLHS70 + DN_v(1,2)*crLHS72 - crLHS683*crLHS74 - crLHS685*crLHS74 + crLHS690); + rLHS(3,6)+=gauss_weight*(DN_v(1,0)*crLHS75 + DN_v(1,1)*crLHS77 + DN_v(1,2)*crLHS79 - crLHS683*crLHS88 - crLHS685*crLHS88 + crLHS691 + crLHS693); + rLHS(3,7)+=gauss_weight*(DN_v(1,0)*crLHS91 + DN_v(1,1)*crLHS93 + DN_v(1,2)*crLHS96 - crLHS683*crLHS99 - crLHS685*crLHS99 + crLHS694); + rLHS(3,8)+=gauss_weight*(DN_v(1,0)*crLHS100 + DN_v(1,1)*crLHS102 + DN_v(1,2)*crLHS104 - crLHS106*crLHS683 - crLHS106*crLHS685 + crLHS695); + rLHS(3,9)+=gauss_weight*(DN_v(1,0)*crLHS107 + DN_v(1,1)*crLHS109 + DN_v(1,2)*crLHS111 - crLHS120*crLHS683 - crLHS120*crLHS685 + crLHS696 + crLHS698); + rLHS(3,10)+=gauss_weight*(DN_v(1,0)*crLHS123 + DN_v(1,1)*crLHS125 + DN_v(1,2)*crLHS128 - crLHS131*crLHS683 - crLHS131*crLHS685 + crLHS699); + rLHS(3,11)+=gauss_weight*(DN_v(1,0)*crLHS132 + DN_v(1,1)*crLHS134 + DN_v(1,2)*crLHS136 - crLHS138*crLHS683 - crLHS138*crLHS685 + crLHS700); + rLHS(3,12)+=gauss_weight*(DN_v(1,0)*crLHS139 + DN_v(1,1)*crLHS141 + DN_v(1,2)*crLHS143 - crLHS152*crLHS683 - crLHS152*crLHS685 + crLHS701 + crLHS703); + rLHS(3,13)+=gauss_weight*(DN_v(1,0)*crLHS155 + DN_v(1,1)*crLHS157 + DN_v(1,2)*crLHS160 - crLHS163*crLHS683 - crLHS163*crLHS685 + crLHS704); + rLHS(3,14)+=gauss_weight*(DN_v(1,0)*crLHS164 + DN_v(1,1)*crLHS166 + DN_v(1,2)*crLHS168 - crLHS170*crLHS683 - crLHS170*crLHS685 + crLHS705); + rLHS(3,15)+=gauss_weight*(DN_v(1,0)*crLHS171 + DN_v(1,1)*crLHS173 + DN_v(1,2)*crLHS175 - crLHS184*crLHS683 - crLHS184*crLHS685 + crLHS706 + crLHS708); + rLHS(3,16)+=gauss_weight*(DN_v(1,0)*crLHS187 + DN_v(1,1)*crLHS189 + DN_v(1,2)*crLHS192 - crLHS195*crLHS683 - crLHS195*crLHS685 + crLHS709); + rLHS(3,17)+=gauss_weight*(DN_v(1,0)*crLHS196 + DN_v(1,1)*crLHS198 + DN_v(1,2)*crLHS200 - crLHS202*crLHS683 - crLHS202*crLHS685 + crLHS710); + rLHS(3,18)+=gauss_weight*(DN_v(1,0)*crLHS203 + DN_v(1,1)*crLHS205 + DN_v(1,2)*crLHS207 - crLHS216*crLHS683 - crLHS216*crLHS685 + crLHS711 + crLHS713); + rLHS(3,19)+=gauss_weight*(DN_v(1,0)*crLHS219 + DN_v(1,1)*crLHS221 + DN_v(1,2)*crLHS224 - crLHS227*crLHS683 - crLHS227*crLHS685 + crLHS714); + rLHS(3,20)+=gauss_weight*(DN_v(1,0)*crLHS228 + DN_v(1,1)*crLHS230 + DN_v(1,2)*crLHS232 - crLHS234*crLHS683 - crLHS234*crLHS685 + crLHS715); + rLHS(3,21)+=gauss_weight*(DN_v(1,0)*crLHS235 + DN_v(1,1)*crLHS237 + DN_v(1,2)*crLHS239 - crLHS248*crLHS683 - crLHS248*crLHS685 + crLHS716 + crLHS718); + rLHS(3,22)+=gauss_weight*(DN_v(1,0)*crLHS251 + DN_v(1,1)*crLHS253 + DN_v(1,2)*crLHS256 - crLHS259*crLHS683 - crLHS259*crLHS685 + crLHS719); + rLHS(3,23)+=gauss_weight*(DN_v(1,0)*crLHS260 + DN_v(1,1)*crLHS262 + DN_v(1,2)*crLHS264 - crLHS266*crLHS683 - crLHS266*crLHS685 + crLHS720); + rLHS(3,24)+=gauss_weight*(DN_v(1,0)*crLHS267 + DN_v(1,1)*crLHS269 + DN_v(1,2)*crLHS271 - crLHS280*crLHS683 - crLHS280*crLHS685 + crLHS721 + crLHS723); + rLHS(3,25)+=gauss_weight*(DN_v(1,0)*crLHS283 + DN_v(1,1)*crLHS285 + DN_v(1,2)*crLHS288 - crLHS291*crLHS683 - crLHS291*crLHS685 + crLHS724); + rLHS(3,26)+=gauss_weight*(DN_v(1,0)*crLHS292 + DN_v(1,1)*crLHS294 + DN_v(1,2)*crLHS296 - crLHS298*crLHS683 - crLHS298*crLHS685 + crLHS725); + rLHS(3,27)+=gauss_weight*(DN_v(1,0)*crLHS299 + DN_v(1,1)*crLHS301 + DN_v(1,2)*crLHS303 - crLHS311*crLHS683 - crLHS311*crLHS685 + crLHS726 + crLHS728); + rLHS(3,28)+=gauss_weight*(DN_v(1,0)*crLHS314 + DN_v(1,1)*crLHS316 + DN_v(1,2)*crLHS319 - crLHS322*crLHS683 - crLHS322*crLHS685 + crLHS729); + rLHS(3,29)+=gauss_weight*(DN_v(1,0)*crLHS323 + DN_v(1,1)*crLHS325 + DN_v(1,2)*crLHS327 - crLHS329*crLHS683 - crLHS329*crLHS685 + crLHS730); + rLHS(3,30)+=gauss_weight*(crLHS331*crLHS53 + crLHS331*crLHS684 + crLHS731); + rLHS(3,31)+=gauss_weight*(crLHS333*crLHS53 + crLHS333*crLHS684 + crLHS732); + rLHS(3,32)+=gauss_weight*(crLHS335*crLHS53 + crLHS335*crLHS684 + crLHS733); + rLHS(3,33)+=gauss_weight*(crLHS337*crLHS53 + crLHS337*crLHS684 + crLHS734); + rLHS(4,0)+=gauss_weight*(DN_v(1,0)*crLHS2 + DN_v(1,1)*crLHS338 + DN_v(1,2)*crLHS339 - crLHS342*crLHS683 - crLHS342*crLHS685 + crLHS65); + rLHS(4,1)+=gauss_weight*(DN_v(1,0)*crLHS28 + DN_v(1,1)*crLHS343 + DN_v(1,2)*crLHS345 - crLHS350*crLHS683 - crLHS350*crLHS685 + crLHS366 + crLHS686); + rLHS(4,2)+=gauss_weight*(DN_v(1,0)*crLHS38 + DN_v(1,1)*crLHS351 + DN_v(1,2)*crLHS353 - crLHS356*crLHS683 - crLHS356*crLHS685 + crLHS555); + rLHS(4,3)+=gauss_weight*(DN_v(1,0)*crLHS45 + DN_v(1,1)*crLHS357 + DN_v(1,2)*crLHS358 - crLHS362*crLHS683 - crLHS362*crLHS685 + crLHS689); + rLHS(4,4)+=gauss_weight*(DN_v(1,0)*crLHS61 + std::pow(DN_v(1,1), 2)*crLHS9 + DN_v(1,1)*crLHS363 + DN_v(1,2)*crLHS365 - crLHS370*crLHS683 - crLHS370*crLHS685 + crLHS687); + rLHS(4,5)+=gauss_weight*(DN_v(1,0)*crLHS70 + DN_v(1,1)*crLHS371 + DN_v(1,2)*crLHS373 - crLHS375*crLHS683 - crLHS375*crLHS685 + crLHS736); + rLHS(4,6)+=gauss_weight*(DN_v(1,0)*crLHS77 + DN_v(1,1)*crLHS376 + DN_v(1,2)*crLHS377 - crLHS381*crLHS683 - crLHS381*crLHS685 + crLHS737); + rLHS(4,7)+=gauss_weight*(DN_v(1,0)*crLHS93 + DN_v(1,1)*crLHS382 + DN_v(1,2)*crLHS384 - crLHS389*crLHS683 - crLHS389*crLHS685 + crLHS693 + crLHS738); + rLHS(4,8)+=gauss_weight*(DN_v(1,0)*crLHS102 + DN_v(1,1)*crLHS390 + DN_v(1,2)*crLHS392 - crLHS394*crLHS683 - crLHS394*crLHS685 + crLHS739); + rLHS(4,9)+=gauss_weight*(DN_v(1,0)*crLHS109 + DN_v(1,1)*crLHS395 + DN_v(1,2)*crLHS396 - crLHS400*crLHS683 - crLHS400*crLHS685 + crLHS740); + rLHS(4,10)+=gauss_weight*(DN_v(1,0)*crLHS125 + DN_v(1,1)*crLHS401 + DN_v(1,2)*crLHS403 - crLHS408*crLHS683 - crLHS408*crLHS685 + crLHS698 + crLHS741); + rLHS(4,11)+=gauss_weight*(DN_v(1,0)*crLHS134 + DN_v(1,1)*crLHS409 + DN_v(1,2)*crLHS411 - crLHS413*crLHS683 - crLHS413*crLHS685 + crLHS742); + rLHS(4,12)+=gauss_weight*(DN_v(1,0)*crLHS141 + DN_v(1,1)*crLHS414 + DN_v(1,2)*crLHS415 - crLHS419*crLHS683 - crLHS419*crLHS685 + crLHS743); + rLHS(4,13)+=gauss_weight*(DN_v(1,0)*crLHS157 + DN_v(1,1)*crLHS420 + DN_v(1,2)*crLHS422 - crLHS427*crLHS683 - crLHS427*crLHS685 + crLHS703 + crLHS744); + rLHS(4,14)+=gauss_weight*(DN_v(1,0)*crLHS166 + DN_v(1,1)*crLHS428 + DN_v(1,2)*crLHS430 - crLHS432*crLHS683 - crLHS432*crLHS685 + crLHS745); + rLHS(4,15)+=gauss_weight*(DN_v(1,0)*crLHS173 + DN_v(1,1)*crLHS433 + DN_v(1,2)*crLHS434 - crLHS438*crLHS683 - crLHS438*crLHS685 + crLHS746); + rLHS(4,16)+=gauss_weight*(DN_v(1,0)*crLHS189 + DN_v(1,1)*crLHS439 + DN_v(1,2)*crLHS441 - crLHS446*crLHS683 - crLHS446*crLHS685 + crLHS708 + crLHS747); + rLHS(4,17)+=gauss_weight*(DN_v(1,0)*crLHS198 + DN_v(1,1)*crLHS447 + DN_v(1,2)*crLHS449 - crLHS451*crLHS683 - crLHS451*crLHS685 + crLHS748); + rLHS(4,18)+=gauss_weight*(DN_v(1,0)*crLHS205 + DN_v(1,1)*crLHS452 + DN_v(1,2)*crLHS453 - crLHS457*crLHS683 - crLHS457*crLHS685 + crLHS749); + rLHS(4,19)+=gauss_weight*(DN_v(1,0)*crLHS221 + DN_v(1,1)*crLHS458 + DN_v(1,2)*crLHS460 - crLHS465*crLHS683 - crLHS465*crLHS685 + crLHS713 + crLHS750); + rLHS(4,20)+=gauss_weight*(DN_v(1,0)*crLHS230 + DN_v(1,1)*crLHS466 + DN_v(1,2)*crLHS468 - crLHS470*crLHS683 - crLHS470*crLHS685 + crLHS751); + rLHS(4,21)+=gauss_weight*(DN_v(1,0)*crLHS237 + DN_v(1,1)*crLHS471 + DN_v(1,2)*crLHS472 - crLHS476*crLHS683 - crLHS476*crLHS685 + crLHS752); + rLHS(4,22)+=gauss_weight*(DN_v(1,0)*crLHS253 + DN_v(1,1)*crLHS477 + DN_v(1,2)*crLHS479 - crLHS484*crLHS683 - crLHS484*crLHS685 + crLHS718 + crLHS753); + rLHS(4,23)+=gauss_weight*(DN_v(1,0)*crLHS262 + DN_v(1,1)*crLHS485 + DN_v(1,2)*crLHS487 - crLHS489*crLHS683 - crLHS489*crLHS685 + crLHS754); + rLHS(4,24)+=gauss_weight*(DN_v(1,0)*crLHS269 + DN_v(1,1)*crLHS490 + DN_v(1,2)*crLHS491 - crLHS495*crLHS683 - crLHS495*crLHS685 + crLHS755); + rLHS(4,25)+=gauss_weight*(DN_v(1,0)*crLHS285 + DN_v(1,1)*crLHS496 + DN_v(1,2)*crLHS498 - crLHS503*crLHS683 - crLHS503*crLHS685 + crLHS723 + crLHS756); + rLHS(4,26)+=gauss_weight*(DN_v(1,0)*crLHS294 + DN_v(1,1)*crLHS504 + DN_v(1,2)*crLHS506 - crLHS508*crLHS683 - crLHS508*crLHS685 + crLHS757); + rLHS(4,27)+=gauss_weight*(DN_v(1,0)*crLHS301 + DN_v(1,1)*crLHS509 + DN_v(1,2)*crLHS510 - crLHS514*crLHS683 - crLHS514*crLHS685 + crLHS758); + rLHS(4,28)+=gauss_weight*(DN_v(1,0)*crLHS316 + DN_v(1,1)*crLHS515 + DN_v(1,2)*crLHS517 - crLHS522*crLHS683 - crLHS522*crLHS685 + crLHS728 + crLHS759); + rLHS(4,29)+=gauss_weight*(DN_v(1,0)*crLHS325 + DN_v(1,1)*crLHS523 + DN_v(1,2)*crLHS525 - crLHS527*crLHS683 - crLHS527*crLHS685 + crLHS760); + rLHS(4,30)+=gauss_weight*(crLHS529*crLHS53 + crLHS529*crLHS684 + crLHS761); + rLHS(4,31)+=gauss_weight*(crLHS53*crLHS531 + crLHS531*crLHS684 + crLHS762); + rLHS(4,32)+=gauss_weight*(crLHS53*crLHS533 + crLHS533*crLHS684 + crLHS763); + rLHS(4,33)+=gauss_weight*(crLHS53*crLHS535 + crLHS535*crLHS684 + crLHS764); + rLHS(5,0)+=gauss_weight*(DN_v(1,0)*crLHS4 + DN_v(1,1)*crLHS339 + DN_v(1,2)*crLHS536 - crLHS539*crLHS683 - crLHS539*crLHS685 + crLHS73); + rLHS(5,1)+=gauss_weight*(DN_v(1,0)*crLHS31 + DN_v(1,1)*crLHS345 + DN_v(1,2)*crLHS540 + crLHS374 - crLHS542*crLHS683 - crLHS542*crLHS685); + rLHS(5,2)+=gauss_weight*(DN_v(1,0)*crLHS40 + DN_v(1,1)*crLHS353 + DN_v(1,2)*crLHS543 - crLHS547*crLHS683 - crLHS547*crLHS685 + crLHS559 + crLHS686); + rLHS(5,3)+=gauss_weight*(DN_v(1,0)*crLHS47 + DN_v(1,1)*crLHS358 + DN_v(1,2)*crLHS548 - crLHS553*crLHS683 - crLHS553*crLHS685 + crLHS690); + rLHS(5,4)+=gauss_weight*(DN_v(1,0)*crLHS64 + DN_v(1,1)*crLHS365 + DN_v(1,2)*crLHS554 - crLHS557*crLHS683 - crLHS557*crLHS685 + crLHS736); + rLHS(5,5)+=gauss_weight*(DN_v(1,0)*crLHS72 + DN_v(1,1)*crLHS373 + std::pow(DN_v(1,2), 2)*crLHS9 + DN_v(1,2)*crLHS558 - crLHS562*crLHS683 - crLHS562*crLHS685 + crLHS687); + rLHS(5,6)+=gauss_weight*(DN_v(1,0)*crLHS79 + DN_v(1,1)*crLHS377 + DN_v(1,2)*crLHS563 - crLHS567*crLHS683 - crLHS567*crLHS685 + crLHS766); + rLHS(5,7)+=gauss_weight*(DN_v(1,0)*crLHS96 + DN_v(1,1)*crLHS384 + DN_v(1,2)*crLHS568 - crLHS571*crLHS683 - crLHS571*crLHS685 + crLHS767); + rLHS(5,8)+=gauss_weight*(DN_v(1,0)*crLHS104 + DN_v(1,1)*crLHS392 + DN_v(1,2)*crLHS572 - crLHS576*crLHS683 - crLHS576*crLHS685 + crLHS693 + crLHS768); + rLHS(5,9)+=gauss_weight*(DN_v(1,0)*crLHS111 + DN_v(1,1)*crLHS396 + DN_v(1,2)*crLHS577 - crLHS581*crLHS683 - crLHS581*crLHS685 + crLHS769); + rLHS(5,10)+=gauss_weight*(DN_v(1,0)*crLHS128 + DN_v(1,1)*crLHS403 + DN_v(1,2)*crLHS582 - crLHS585*crLHS683 - crLHS585*crLHS685 + crLHS770); + rLHS(5,11)+=gauss_weight*(DN_v(1,0)*crLHS136 + DN_v(1,1)*crLHS411 + DN_v(1,2)*crLHS586 - crLHS590*crLHS683 - crLHS590*crLHS685 + crLHS698 + crLHS771); + rLHS(5,12)+=gauss_weight*(DN_v(1,0)*crLHS143 + DN_v(1,1)*crLHS415 + DN_v(1,2)*crLHS591 - crLHS595*crLHS683 - crLHS595*crLHS685 + crLHS772); + rLHS(5,13)+=gauss_weight*(DN_v(1,0)*crLHS160 + DN_v(1,1)*crLHS422 + DN_v(1,2)*crLHS596 - crLHS599*crLHS683 - crLHS599*crLHS685 + crLHS773); + rLHS(5,14)+=gauss_weight*(DN_v(1,0)*crLHS168 + DN_v(1,1)*crLHS430 + DN_v(1,2)*crLHS600 - crLHS604*crLHS683 - crLHS604*crLHS685 + crLHS703 + crLHS774); + rLHS(5,15)+=gauss_weight*(DN_v(1,0)*crLHS175 + DN_v(1,1)*crLHS434 + DN_v(1,2)*crLHS605 - crLHS609*crLHS683 - crLHS609*crLHS685 + crLHS775); + rLHS(5,16)+=gauss_weight*(DN_v(1,0)*crLHS192 + DN_v(1,1)*crLHS441 + DN_v(1,2)*crLHS610 - crLHS613*crLHS683 - crLHS613*crLHS685 + crLHS776); + rLHS(5,17)+=gauss_weight*(DN_v(1,0)*crLHS200 + DN_v(1,1)*crLHS449 + DN_v(1,2)*crLHS614 - crLHS618*crLHS683 - crLHS618*crLHS685 + crLHS708 + crLHS777); + rLHS(5,18)+=gauss_weight*(DN_v(1,0)*crLHS207 + DN_v(1,1)*crLHS453 + DN_v(1,2)*crLHS619 - crLHS623*crLHS683 - crLHS623*crLHS685 + crLHS778); + rLHS(5,19)+=gauss_weight*(DN_v(1,0)*crLHS224 + DN_v(1,1)*crLHS460 + DN_v(1,2)*crLHS624 - crLHS627*crLHS683 - crLHS627*crLHS685 + crLHS779); + rLHS(5,20)+=gauss_weight*(DN_v(1,0)*crLHS232 + DN_v(1,1)*crLHS468 + DN_v(1,2)*crLHS628 - crLHS632*crLHS683 - crLHS632*crLHS685 + crLHS713 + crLHS780); + rLHS(5,21)+=gauss_weight*(DN_v(1,0)*crLHS239 + DN_v(1,1)*crLHS472 + DN_v(1,2)*crLHS633 - crLHS637*crLHS683 - crLHS637*crLHS685 + crLHS781); + rLHS(5,22)+=gauss_weight*(DN_v(1,0)*crLHS256 + DN_v(1,1)*crLHS479 + DN_v(1,2)*crLHS638 - crLHS641*crLHS683 - crLHS641*crLHS685 + crLHS782); + rLHS(5,23)+=gauss_weight*(DN_v(1,0)*crLHS264 + DN_v(1,1)*crLHS487 + DN_v(1,2)*crLHS642 - crLHS646*crLHS683 - crLHS646*crLHS685 + crLHS718 + crLHS783); + rLHS(5,24)+=gauss_weight*(DN_v(1,0)*crLHS271 + DN_v(1,1)*crLHS491 + DN_v(1,2)*crLHS647 - crLHS651*crLHS683 - crLHS651*crLHS685 + crLHS784); + rLHS(5,25)+=gauss_weight*(DN_v(1,0)*crLHS288 + DN_v(1,1)*crLHS498 + DN_v(1,2)*crLHS652 - crLHS655*crLHS683 - crLHS655*crLHS685 + crLHS785); + rLHS(5,26)+=gauss_weight*(DN_v(1,0)*crLHS296 + DN_v(1,1)*crLHS506 + DN_v(1,2)*crLHS656 - crLHS660*crLHS683 - crLHS660*crLHS685 + crLHS723 + crLHS786); + rLHS(5,27)+=gauss_weight*(DN_v(1,0)*crLHS303 + DN_v(1,1)*crLHS510 + DN_v(1,2)*crLHS661 - crLHS665*crLHS683 - crLHS665*crLHS685 + crLHS787); + rLHS(5,28)+=gauss_weight*(DN_v(1,0)*crLHS319 + DN_v(1,1)*crLHS517 + DN_v(1,2)*crLHS666 - crLHS669*crLHS683 - crLHS669*crLHS685 + crLHS788); + rLHS(5,29)+=gauss_weight*(DN_v(1,0)*crLHS327 + DN_v(1,1)*crLHS525 + DN_v(1,2)*crLHS670 - crLHS674*crLHS683 - crLHS674*crLHS685 + crLHS728 + crLHS789); + rLHS(5,30)+=gauss_weight*(crLHS53*crLHS676 + crLHS676*crLHS684 + crLHS790); + rLHS(5,31)+=gauss_weight*(crLHS53*crLHS678 + crLHS678*crLHS684 + crLHS791); + rLHS(5,32)+=gauss_weight*(crLHS53*crLHS680 + crLHS680*crLHS684 + crLHS792); + rLHS(5,33)+=gauss_weight*(crLHS53*crLHS682 + crLHS682*crLHS684 + crLHS793); + rLHS(6,0)+=gauss_weight*(DN_v(2,0)*crLHS0 + DN_v(2,1)*crLHS2 + DN_v(2,2)*crLHS4 - crLHS19*crLHS794 - crLHS19*crLHS796 + crLHS797 + crLHS80); + rLHS(6,1)+=gauss_weight*(DN_v(2,0)*crLHS26 + DN_v(2,1)*crLHS28 + DN_v(2,2)*crLHS31 - crLHS35*crLHS794 - crLHS35*crLHS796 + crLHS378); + rLHS(6,2)+=gauss_weight*(DN_v(2,0)*crLHS36 + DN_v(2,1)*crLHS38 + DN_v(2,2)*crLHS40 - crLHS42*crLHS794 - crLHS42*crLHS796 + crLHS564); + rLHS(6,3)+=gauss_weight*(DN_v(2,0)*crLHS43 + DN_v(2,1)*crLHS45 + DN_v(2,2)*crLHS47 - crLHS56*crLHS794 - crLHS56*crLHS796 + crLHS691 + crLHS798); + rLHS(6,4)+=gauss_weight*(DN_v(2,0)*crLHS59 + DN_v(2,1)*crLHS61 + DN_v(2,2)*crLHS64 - crLHS67*crLHS794 - crLHS67*crLHS796 + crLHS737); + rLHS(6,5)+=gauss_weight*(DN_v(2,0)*crLHS68 + DN_v(2,1)*crLHS70 + DN_v(2,2)*crLHS72 - crLHS74*crLHS794 - crLHS74*crLHS796 + crLHS766); + rLHS(6,6)+=gauss_weight*(std::pow(DN_v(2,0), 2)*crLHS9 + DN_v(2,0)*crLHS75 + DN_v(2,1)*crLHS77 + DN_v(2,2)*crLHS79 - crLHS794*crLHS88 - crLHS796*crLHS88 + crLHS799); + rLHS(6,7)+=gauss_weight*(DN_v(2,0)*crLHS91 + DN_v(2,1)*crLHS93 + DN_v(2,2)*crLHS96 - crLHS794*crLHS99 - crLHS796*crLHS99 + crLHS801); + rLHS(6,8)+=gauss_weight*(DN_v(2,0)*crLHS100 + DN_v(2,1)*crLHS102 + DN_v(2,2)*crLHS104 - crLHS106*crLHS794 - crLHS106*crLHS796 + crLHS802); + rLHS(6,9)+=gauss_weight*(DN_v(2,0)*crLHS107 + DN_v(2,1)*crLHS109 + DN_v(2,2)*crLHS111 - crLHS120*crLHS794 - crLHS120*crLHS796 + crLHS803 + crLHS805); + rLHS(6,10)+=gauss_weight*(DN_v(2,0)*crLHS123 + DN_v(2,1)*crLHS125 + DN_v(2,2)*crLHS128 - crLHS131*crLHS794 - crLHS131*crLHS796 + crLHS806); + rLHS(6,11)+=gauss_weight*(DN_v(2,0)*crLHS132 + DN_v(2,1)*crLHS134 + DN_v(2,2)*crLHS136 - crLHS138*crLHS794 - crLHS138*crLHS796 + crLHS807); + rLHS(6,12)+=gauss_weight*(DN_v(2,0)*crLHS139 + DN_v(2,1)*crLHS141 + DN_v(2,2)*crLHS143 - crLHS152*crLHS794 - crLHS152*crLHS796 + crLHS808 + crLHS810); + rLHS(6,13)+=gauss_weight*(DN_v(2,0)*crLHS155 + DN_v(2,1)*crLHS157 + DN_v(2,2)*crLHS160 - crLHS163*crLHS794 - crLHS163*crLHS796 + crLHS811); + rLHS(6,14)+=gauss_weight*(DN_v(2,0)*crLHS164 + DN_v(2,1)*crLHS166 + DN_v(2,2)*crLHS168 - crLHS170*crLHS794 - crLHS170*crLHS796 + crLHS812); + rLHS(6,15)+=gauss_weight*(DN_v(2,0)*crLHS171 + DN_v(2,1)*crLHS173 + DN_v(2,2)*crLHS175 - crLHS184*crLHS794 - crLHS184*crLHS796 + crLHS813 + crLHS815); + rLHS(6,16)+=gauss_weight*(DN_v(2,0)*crLHS187 + DN_v(2,1)*crLHS189 + DN_v(2,2)*crLHS192 - crLHS195*crLHS794 - crLHS195*crLHS796 + crLHS816); + rLHS(6,17)+=gauss_weight*(DN_v(2,0)*crLHS196 + DN_v(2,1)*crLHS198 + DN_v(2,2)*crLHS200 - crLHS202*crLHS794 - crLHS202*crLHS796 + crLHS817); + rLHS(6,18)+=gauss_weight*(DN_v(2,0)*crLHS203 + DN_v(2,1)*crLHS205 + DN_v(2,2)*crLHS207 - crLHS216*crLHS794 - crLHS216*crLHS796 + crLHS818 + crLHS820); + rLHS(6,19)+=gauss_weight*(DN_v(2,0)*crLHS219 + DN_v(2,1)*crLHS221 + DN_v(2,2)*crLHS224 - crLHS227*crLHS794 - crLHS227*crLHS796 + crLHS821); + rLHS(6,20)+=gauss_weight*(DN_v(2,0)*crLHS228 + DN_v(2,1)*crLHS230 + DN_v(2,2)*crLHS232 - crLHS234*crLHS794 - crLHS234*crLHS796 + crLHS822); + rLHS(6,21)+=gauss_weight*(DN_v(2,0)*crLHS235 + DN_v(2,1)*crLHS237 + DN_v(2,2)*crLHS239 - crLHS248*crLHS794 - crLHS248*crLHS796 + crLHS823 + crLHS825); + rLHS(6,22)+=gauss_weight*(DN_v(2,0)*crLHS251 + DN_v(2,1)*crLHS253 + DN_v(2,2)*crLHS256 - crLHS259*crLHS794 - crLHS259*crLHS796 + crLHS826); + rLHS(6,23)+=gauss_weight*(DN_v(2,0)*crLHS260 + DN_v(2,1)*crLHS262 + DN_v(2,2)*crLHS264 - crLHS266*crLHS794 - crLHS266*crLHS796 + crLHS827); + rLHS(6,24)+=gauss_weight*(DN_v(2,0)*crLHS267 + DN_v(2,1)*crLHS269 + DN_v(2,2)*crLHS271 - crLHS280*crLHS794 - crLHS280*crLHS796 + crLHS828 + crLHS830); + rLHS(6,25)+=gauss_weight*(DN_v(2,0)*crLHS283 + DN_v(2,1)*crLHS285 + DN_v(2,2)*crLHS288 - crLHS291*crLHS794 - crLHS291*crLHS796 + crLHS831); + rLHS(6,26)+=gauss_weight*(DN_v(2,0)*crLHS292 + DN_v(2,1)*crLHS294 + DN_v(2,2)*crLHS296 - crLHS298*crLHS794 - crLHS298*crLHS796 + crLHS832); + rLHS(6,27)+=gauss_weight*(DN_v(2,0)*crLHS299 + DN_v(2,1)*crLHS301 + DN_v(2,2)*crLHS303 - crLHS311*crLHS794 - crLHS311*crLHS796 + crLHS833 + crLHS835); + rLHS(6,28)+=gauss_weight*(DN_v(2,0)*crLHS314 + DN_v(2,1)*crLHS316 + DN_v(2,2)*crLHS319 - crLHS322*crLHS794 - crLHS322*crLHS796 + crLHS836); + rLHS(6,29)+=gauss_weight*(DN_v(2,0)*crLHS323 + DN_v(2,1)*crLHS325 + DN_v(2,2)*crLHS327 - crLHS329*crLHS794 - crLHS329*crLHS796 + crLHS837); + rLHS(6,30)+=gauss_weight*(crLHS331*crLHS795 + crLHS331*crLHS85 + crLHS838); + rLHS(6,31)+=gauss_weight*(crLHS333*crLHS795 + crLHS333*crLHS85 + crLHS839); + rLHS(6,32)+=gauss_weight*(crLHS335*crLHS795 + crLHS335*crLHS85 + crLHS840); + rLHS(6,33)+=gauss_weight*(crLHS337*crLHS795 + crLHS337*crLHS85 + crLHS841); + rLHS(7,0)+=gauss_weight*(DN_v(2,0)*crLHS2 + DN_v(2,1)*crLHS338 + DN_v(2,2)*crLHS339 - crLHS342*crLHS794 - crLHS342*crLHS796 + crLHS97); + rLHS(7,1)+=gauss_weight*(DN_v(2,0)*crLHS28 + DN_v(2,1)*crLHS343 + DN_v(2,2)*crLHS345 - crLHS350*crLHS794 - crLHS350*crLHS796 + crLHS385 + crLHS797); + rLHS(7,2)+=gauss_weight*(DN_v(2,0)*crLHS38 + DN_v(2,1)*crLHS351 + DN_v(2,2)*crLHS353 - crLHS356*crLHS794 - crLHS356*crLHS796 + crLHS569); + rLHS(7,3)+=gauss_weight*(DN_v(2,0)*crLHS45 + DN_v(2,1)*crLHS357 + DN_v(2,2)*crLHS358 - crLHS362*crLHS794 - crLHS362*crLHS796 + crLHS694); + rLHS(7,4)+=gauss_weight*(DN_v(2,0)*crLHS61 + DN_v(2,1)*crLHS363 + DN_v(2,2)*crLHS365 - crLHS370*crLHS794 - crLHS370*crLHS796 + crLHS738 + crLHS798); + rLHS(7,5)+=gauss_weight*(DN_v(2,0)*crLHS70 + DN_v(2,1)*crLHS371 + DN_v(2,2)*crLHS373 - crLHS375*crLHS794 - crLHS375*crLHS796 + crLHS767); + rLHS(7,6)+=gauss_weight*(DN_v(2,0)*crLHS77 + DN_v(2,1)*crLHS376 + DN_v(2,2)*crLHS377 - crLHS381*crLHS794 - crLHS381*crLHS796 + crLHS801); + rLHS(7,7)+=gauss_weight*(DN_v(2,0)*crLHS93 + std::pow(DN_v(2,1), 2)*crLHS9 + DN_v(2,1)*crLHS382 + DN_v(2,2)*crLHS384 - crLHS389*crLHS794 - crLHS389*crLHS796 + crLHS799); + rLHS(7,8)+=gauss_weight*(DN_v(2,0)*crLHS102 + DN_v(2,1)*crLHS390 + DN_v(2,2)*crLHS392 - crLHS394*crLHS794 - crLHS394*crLHS796 + crLHS843); + rLHS(7,9)+=gauss_weight*(DN_v(2,0)*crLHS109 + DN_v(2,1)*crLHS395 + DN_v(2,2)*crLHS396 - crLHS400*crLHS794 - crLHS400*crLHS796 + crLHS844); + rLHS(7,10)+=gauss_weight*(DN_v(2,0)*crLHS125 + DN_v(2,1)*crLHS401 + DN_v(2,2)*crLHS403 - crLHS408*crLHS794 - crLHS408*crLHS796 + crLHS805 + crLHS845); + rLHS(7,11)+=gauss_weight*(DN_v(2,0)*crLHS134 + DN_v(2,1)*crLHS409 + DN_v(2,2)*crLHS411 - crLHS413*crLHS794 - crLHS413*crLHS796 + crLHS846); + rLHS(7,12)+=gauss_weight*(DN_v(2,0)*crLHS141 + DN_v(2,1)*crLHS414 + DN_v(2,2)*crLHS415 - crLHS419*crLHS794 - crLHS419*crLHS796 + crLHS847); + rLHS(7,13)+=gauss_weight*(DN_v(2,0)*crLHS157 + DN_v(2,1)*crLHS420 + DN_v(2,2)*crLHS422 - crLHS427*crLHS794 - crLHS427*crLHS796 + crLHS810 + crLHS848); + rLHS(7,14)+=gauss_weight*(DN_v(2,0)*crLHS166 + DN_v(2,1)*crLHS428 + DN_v(2,2)*crLHS430 - crLHS432*crLHS794 - crLHS432*crLHS796 + crLHS849); + rLHS(7,15)+=gauss_weight*(DN_v(2,0)*crLHS173 + DN_v(2,1)*crLHS433 + DN_v(2,2)*crLHS434 - crLHS438*crLHS794 - crLHS438*crLHS796 + crLHS850); + rLHS(7,16)+=gauss_weight*(DN_v(2,0)*crLHS189 + DN_v(2,1)*crLHS439 + DN_v(2,2)*crLHS441 - crLHS446*crLHS794 - crLHS446*crLHS796 + crLHS815 + crLHS851); + rLHS(7,17)+=gauss_weight*(DN_v(2,0)*crLHS198 + DN_v(2,1)*crLHS447 + DN_v(2,2)*crLHS449 - crLHS451*crLHS794 - crLHS451*crLHS796 + crLHS852); + rLHS(7,18)+=gauss_weight*(DN_v(2,0)*crLHS205 + DN_v(2,1)*crLHS452 + DN_v(2,2)*crLHS453 - crLHS457*crLHS794 - crLHS457*crLHS796 + crLHS853); + rLHS(7,19)+=gauss_weight*(DN_v(2,0)*crLHS221 + DN_v(2,1)*crLHS458 + DN_v(2,2)*crLHS460 - crLHS465*crLHS794 - crLHS465*crLHS796 + crLHS820 + crLHS854); + rLHS(7,20)+=gauss_weight*(DN_v(2,0)*crLHS230 + DN_v(2,1)*crLHS466 + DN_v(2,2)*crLHS468 - crLHS470*crLHS794 - crLHS470*crLHS796 + crLHS855); + rLHS(7,21)+=gauss_weight*(DN_v(2,0)*crLHS237 + DN_v(2,1)*crLHS471 + DN_v(2,2)*crLHS472 - crLHS476*crLHS794 - crLHS476*crLHS796 + crLHS856); + rLHS(7,22)+=gauss_weight*(DN_v(2,0)*crLHS253 + DN_v(2,1)*crLHS477 + DN_v(2,2)*crLHS479 - crLHS484*crLHS794 - crLHS484*crLHS796 + crLHS825 + crLHS857); + rLHS(7,23)+=gauss_weight*(DN_v(2,0)*crLHS262 + DN_v(2,1)*crLHS485 + DN_v(2,2)*crLHS487 - crLHS489*crLHS794 - crLHS489*crLHS796 + crLHS858); + rLHS(7,24)+=gauss_weight*(DN_v(2,0)*crLHS269 + DN_v(2,1)*crLHS490 + DN_v(2,2)*crLHS491 - crLHS495*crLHS794 - crLHS495*crLHS796 + crLHS859); + rLHS(7,25)+=gauss_weight*(DN_v(2,0)*crLHS285 + DN_v(2,1)*crLHS496 + DN_v(2,2)*crLHS498 - crLHS503*crLHS794 - crLHS503*crLHS796 + crLHS830 + crLHS860); + rLHS(7,26)+=gauss_weight*(DN_v(2,0)*crLHS294 + DN_v(2,1)*crLHS504 + DN_v(2,2)*crLHS506 - crLHS508*crLHS794 - crLHS508*crLHS796 + crLHS861); + rLHS(7,27)+=gauss_weight*(DN_v(2,0)*crLHS301 + DN_v(2,1)*crLHS509 + DN_v(2,2)*crLHS510 - crLHS514*crLHS794 - crLHS514*crLHS796 + crLHS862); + rLHS(7,28)+=gauss_weight*(DN_v(2,0)*crLHS316 + DN_v(2,1)*crLHS515 + DN_v(2,2)*crLHS517 - crLHS522*crLHS794 - crLHS522*crLHS796 + crLHS835 + crLHS863); + rLHS(7,29)+=gauss_weight*(DN_v(2,0)*crLHS325 + DN_v(2,1)*crLHS523 + DN_v(2,2)*crLHS525 - crLHS527*crLHS794 - crLHS527*crLHS796 + crLHS864); + rLHS(7,30)+=gauss_weight*(crLHS529*crLHS795 + crLHS529*crLHS85 + crLHS865); + rLHS(7,31)+=gauss_weight*(crLHS531*crLHS795 + crLHS531*crLHS85 + crLHS866); + rLHS(7,32)+=gauss_weight*(crLHS533*crLHS795 + crLHS533*crLHS85 + crLHS867); + rLHS(7,33)+=gauss_weight*(crLHS535*crLHS795 + crLHS535*crLHS85 + crLHS868); + rLHS(8,0)+=gauss_weight*(DN_v(2,0)*crLHS4 + DN_v(2,1)*crLHS339 + DN_v(2,2)*crLHS536 + crLHS105 - crLHS539*crLHS794 - crLHS539*crLHS796); + rLHS(8,1)+=gauss_weight*(DN_v(2,0)*crLHS31 + DN_v(2,1)*crLHS345 + DN_v(2,2)*crLHS540 + crLHS393 - crLHS542*crLHS794 - crLHS542*crLHS796); + rLHS(8,2)+=gauss_weight*(DN_v(2,0)*crLHS40 + DN_v(2,1)*crLHS353 + DN_v(2,2)*crLHS543 - crLHS547*crLHS794 - crLHS547*crLHS796 + crLHS573 + crLHS797); + rLHS(8,3)+=gauss_weight*(DN_v(2,0)*crLHS47 + DN_v(2,1)*crLHS358 + DN_v(2,2)*crLHS548 - crLHS553*crLHS794 - crLHS553*crLHS796 + crLHS695); + rLHS(8,4)+=gauss_weight*(DN_v(2,0)*crLHS64 + DN_v(2,1)*crLHS365 + DN_v(2,2)*crLHS554 - crLHS557*crLHS794 - crLHS557*crLHS796 + crLHS739); + rLHS(8,5)+=gauss_weight*(DN_v(2,0)*crLHS72 + DN_v(2,1)*crLHS373 + DN_v(2,2)*crLHS558 - crLHS562*crLHS794 - crLHS562*crLHS796 + crLHS768 + crLHS798); + rLHS(8,6)+=gauss_weight*(DN_v(2,0)*crLHS79 + DN_v(2,1)*crLHS377 + DN_v(2,2)*crLHS563 - crLHS567*crLHS794 - crLHS567*crLHS796 + crLHS802); + rLHS(8,7)+=gauss_weight*(DN_v(2,0)*crLHS96 + DN_v(2,1)*crLHS384 + DN_v(2,2)*crLHS568 - crLHS571*crLHS794 - crLHS571*crLHS796 + crLHS843); + rLHS(8,8)+=gauss_weight*(DN_v(2,0)*crLHS104 + DN_v(2,1)*crLHS392 + std::pow(DN_v(2,2), 2)*crLHS9 + DN_v(2,2)*crLHS572 - crLHS576*crLHS794 - crLHS576*crLHS796 + crLHS799); + rLHS(8,9)+=gauss_weight*(DN_v(2,0)*crLHS111 + DN_v(2,1)*crLHS396 + DN_v(2,2)*crLHS577 - crLHS581*crLHS794 - crLHS581*crLHS796 + crLHS870); + rLHS(8,10)+=gauss_weight*(DN_v(2,0)*crLHS128 + DN_v(2,1)*crLHS403 + DN_v(2,2)*crLHS582 - crLHS585*crLHS794 - crLHS585*crLHS796 + crLHS871); + rLHS(8,11)+=gauss_weight*(DN_v(2,0)*crLHS136 + DN_v(2,1)*crLHS411 + DN_v(2,2)*crLHS586 - crLHS590*crLHS794 - crLHS590*crLHS796 + crLHS805 + crLHS872); + rLHS(8,12)+=gauss_weight*(DN_v(2,0)*crLHS143 + DN_v(2,1)*crLHS415 + DN_v(2,2)*crLHS591 - crLHS595*crLHS794 - crLHS595*crLHS796 + crLHS873); + rLHS(8,13)+=gauss_weight*(DN_v(2,0)*crLHS160 + DN_v(2,1)*crLHS422 + DN_v(2,2)*crLHS596 - crLHS599*crLHS794 - crLHS599*crLHS796 + crLHS874); + rLHS(8,14)+=gauss_weight*(DN_v(2,0)*crLHS168 + DN_v(2,1)*crLHS430 + DN_v(2,2)*crLHS600 - crLHS604*crLHS794 - crLHS604*crLHS796 + crLHS810 + crLHS875); + rLHS(8,15)+=gauss_weight*(DN_v(2,0)*crLHS175 + DN_v(2,1)*crLHS434 + DN_v(2,2)*crLHS605 - crLHS609*crLHS794 - crLHS609*crLHS796 + crLHS876); + rLHS(8,16)+=gauss_weight*(DN_v(2,0)*crLHS192 + DN_v(2,1)*crLHS441 + DN_v(2,2)*crLHS610 - crLHS613*crLHS794 - crLHS613*crLHS796 + crLHS877); + rLHS(8,17)+=gauss_weight*(DN_v(2,0)*crLHS200 + DN_v(2,1)*crLHS449 + DN_v(2,2)*crLHS614 - crLHS618*crLHS794 - crLHS618*crLHS796 + crLHS815 + crLHS878); + rLHS(8,18)+=gauss_weight*(DN_v(2,0)*crLHS207 + DN_v(2,1)*crLHS453 + DN_v(2,2)*crLHS619 - crLHS623*crLHS794 - crLHS623*crLHS796 + crLHS879); + rLHS(8,19)+=gauss_weight*(DN_v(2,0)*crLHS224 + DN_v(2,1)*crLHS460 + DN_v(2,2)*crLHS624 - crLHS627*crLHS794 - crLHS627*crLHS796 + crLHS880); + rLHS(8,20)+=gauss_weight*(DN_v(2,0)*crLHS232 + DN_v(2,1)*crLHS468 + DN_v(2,2)*crLHS628 - crLHS632*crLHS794 - crLHS632*crLHS796 + crLHS820 + crLHS881); + rLHS(8,21)+=gauss_weight*(DN_v(2,0)*crLHS239 + DN_v(2,1)*crLHS472 + DN_v(2,2)*crLHS633 - crLHS637*crLHS794 - crLHS637*crLHS796 + crLHS882); + rLHS(8,22)+=gauss_weight*(DN_v(2,0)*crLHS256 + DN_v(2,1)*crLHS479 + DN_v(2,2)*crLHS638 - crLHS641*crLHS794 - crLHS641*crLHS796 + crLHS883); + rLHS(8,23)+=gauss_weight*(DN_v(2,0)*crLHS264 + DN_v(2,1)*crLHS487 + DN_v(2,2)*crLHS642 - crLHS646*crLHS794 - crLHS646*crLHS796 + crLHS825 + crLHS884); + rLHS(8,24)+=gauss_weight*(DN_v(2,0)*crLHS271 + DN_v(2,1)*crLHS491 + DN_v(2,2)*crLHS647 - crLHS651*crLHS794 - crLHS651*crLHS796 + crLHS885); + rLHS(8,25)+=gauss_weight*(DN_v(2,0)*crLHS288 + DN_v(2,1)*crLHS498 + DN_v(2,2)*crLHS652 - crLHS655*crLHS794 - crLHS655*crLHS796 + crLHS886); + rLHS(8,26)+=gauss_weight*(DN_v(2,0)*crLHS296 + DN_v(2,1)*crLHS506 + DN_v(2,2)*crLHS656 - crLHS660*crLHS794 - crLHS660*crLHS796 + crLHS830 + crLHS887); + rLHS(8,27)+=gauss_weight*(DN_v(2,0)*crLHS303 + DN_v(2,1)*crLHS510 + DN_v(2,2)*crLHS661 - crLHS665*crLHS794 - crLHS665*crLHS796 + crLHS888); + rLHS(8,28)+=gauss_weight*(DN_v(2,0)*crLHS319 + DN_v(2,1)*crLHS517 + DN_v(2,2)*crLHS666 - crLHS669*crLHS794 - crLHS669*crLHS796 + crLHS889); + rLHS(8,29)+=gauss_weight*(DN_v(2,0)*crLHS327 + DN_v(2,1)*crLHS525 + DN_v(2,2)*crLHS670 - crLHS674*crLHS794 - crLHS674*crLHS796 + crLHS835 + crLHS890); + rLHS(8,30)+=gauss_weight*(crLHS676*crLHS795 + crLHS676*crLHS85 + crLHS891); + rLHS(8,31)+=gauss_weight*(crLHS678*crLHS795 + crLHS678*crLHS85 + crLHS892); + rLHS(8,32)+=gauss_weight*(crLHS680*crLHS795 + crLHS680*crLHS85 + crLHS893); + rLHS(8,33)+=gauss_weight*(crLHS682*crLHS795 + crLHS682*crLHS85 + crLHS894); + rLHS(9,0)+=gauss_weight*(DN_v(3,0)*crLHS0 + DN_v(3,1)*crLHS2 + DN_v(3,2)*crLHS4 + crLHS112 - crLHS19*crLHS895 - crLHS19*crLHS897 + crLHS898); + rLHS(9,1)+=gauss_weight*(DN_v(3,0)*crLHS26 + DN_v(3,1)*crLHS28 + DN_v(3,2)*crLHS31 - crLHS35*crLHS895 - crLHS35*crLHS897 + crLHS397); + rLHS(9,2)+=gauss_weight*(DN_v(3,0)*crLHS36 + DN_v(3,1)*crLHS38 + DN_v(3,2)*crLHS40 - crLHS42*crLHS895 - crLHS42*crLHS897 + crLHS578); + rLHS(9,3)+=gauss_weight*(DN_v(3,0)*crLHS43 + DN_v(3,1)*crLHS45 + DN_v(3,2)*crLHS47 - crLHS56*crLHS895 - crLHS56*crLHS897 + crLHS696 + crLHS899); + rLHS(9,4)+=gauss_weight*(DN_v(3,0)*crLHS59 + DN_v(3,1)*crLHS61 + DN_v(3,2)*crLHS64 - crLHS67*crLHS895 - crLHS67*crLHS897 + crLHS740); + rLHS(9,5)+=gauss_weight*(DN_v(3,0)*crLHS68 + DN_v(3,1)*crLHS70 + DN_v(3,2)*crLHS72 - crLHS74*crLHS895 - crLHS74*crLHS897 + crLHS769); + rLHS(9,6)+=gauss_weight*(DN_v(3,0)*crLHS75 + DN_v(3,1)*crLHS77 + DN_v(3,2)*crLHS79 + crLHS803 - crLHS88*crLHS895 - crLHS88*crLHS897 + crLHS900); + rLHS(9,7)+=gauss_weight*(DN_v(3,0)*crLHS91 + DN_v(3,1)*crLHS93 + DN_v(3,2)*crLHS96 + crLHS844 - crLHS895*crLHS99 - crLHS897*crLHS99); + rLHS(9,8)+=gauss_weight*(DN_v(3,0)*crLHS100 + DN_v(3,1)*crLHS102 + DN_v(3,2)*crLHS104 - crLHS106*crLHS895 - crLHS106*crLHS897 + crLHS870); + rLHS(9,9)+=gauss_weight*(std::pow(DN_v(3,0), 2)*crLHS9 + DN_v(3,0)*crLHS107 + DN_v(3,1)*crLHS109 + DN_v(3,2)*crLHS111 - crLHS120*crLHS895 - crLHS120*crLHS897 + crLHS901); + rLHS(9,10)+=gauss_weight*(DN_v(3,0)*crLHS123 + DN_v(3,1)*crLHS125 + DN_v(3,2)*crLHS128 - crLHS131*crLHS895 - crLHS131*crLHS897 + crLHS903); + rLHS(9,11)+=gauss_weight*(DN_v(3,0)*crLHS132 + DN_v(3,1)*crLHS134 + DN_v(3,2)*crLHS136 - crLHS138*crLHS895 - crLHS138*crLHS897 + crLHS904); + rLHS(9,12)+=gauss_weight*(DN_v(3,0)*crLHS139 + DN_v(3,1)*crLHS141 + DN_v(3,2)*crLHS143 - crLHS152*crLHS895 - crLHS152*crLHS897 + crLHS905 + crLHS907); + rLHS(9,13)+=gauss_weight*(DN_v(3,0)*crLHS155 + DN_v(3,1)*crLHS157 + DN_v(3,2)*crLHS160 - crLHS163*crLHS895 - crLHS163*crLHS897 + crLHS908); + rLHS(9,14)+=gauss_weight*(DN_v(3,0)*crLHS164 + DN_v(3,1)*crLHS166 + DN_v(3,2)*crLHS168 - crLHS170*crLHS895 - crLHS170*crLHS897 + crLHS909); + rLHS(9,15)+=gauss_weight*(DN_v(3,0)*crLHS171 + DN_v(3,1)*crLHS173 + DN_v(3,2)*crLHS175 - crLHS184*crLHS895 - crLHS184*crLHS897 + crLHS910 + crLHS912); + rLHS(9,16)+=gauss_weight*(DN_v(3,0)*crLHS187 + DN_v(3,1)*crLHS189 + DN_v(3,2)*crLHS192 - crLHS195*crLHS895 - crLHS195*crLHS897 + crLHS913); + rLHS(9,17)+=gauss_weight*(DN_v(3,0)*crLHS196 + DN_v(3,1)*crLHS198 + DN_v(3,2)*crLHS200 - crLHS202*crLHS895 - crLHS202*crLHS897 + crLHS914); + rLHS(9,18)+=gauss_weight*(DN_v(3,0)*crLHS203 + DN_v(3,1)*crLHS205 + DN_v(3,2)*crLHS207 - crLHS216*crLHS895 - crLHS216*crLHS897 + crLHS915 + crLHS917); + rLHS(9,19)+=gauss_weight*(DN_v(3,0)*crLHS219 + DN_v(3,1)*crLHS221 + DN_v(3,2)*crLHS224 - crLHS227*crLHS895 - crLHS227*crLHS897 + crLHS918); + rLHS(9,20)+=gauss_weight*(DN_v(3,0)*crLHS228 + DN_v(3,1)*crLHS230 + DN_v(3,2)*crLHS232 - crLHS234*crLHS895 - crLHS234*crLHS897 + crLHS919); + rLHS(9,21)+=gauss_weight*(DN_v(3,0)*crLHS235 + DN_v(3,1)*crLHS237 + DN_v(3,2)*crLHS239 - crLHS248*crLHS895 - crLHS248*crLHS897 + crLHS920 + crLHS922); + rLHS(9,22)+=gauss_weight*(DN_v(3,0)*crLHS251 + DN_v(3,1)*crLHS253 + DN_v(3,2)*crLHS256 - crLHS259*crLHS895 - crLHS259*crLHS897 + crLHS923); + rLHS(9,23)+=gauss_weight*(DN_v(3,0)*crLHS260 + DN_v(3,1)*crLHS262 + DN_v(3,2)*crLHS264 - crLHS266*crLHS895 - crLHS266*crLHS897 + crLHS924); + rLHS(9,24)+=gauss_weight*(DN_v(3,0)*crLHS267 + DN_v(3,1)*crLHS269 + DN_v(3,2)*crLHS271 - crLHS280*crLHS895 - crLHS280*crLHS897 + crLHS925 + crLHS927); + rLHS(9,25)+=gauss_weight*(DN_v(3,0)*crLHS283 + DN_v(3,1)*crLHS285 + DN_v(3,2)*crLHS288 - crLHS291*crLHS895 - crLHS291*crLHS897 + crLHS928); + rLHS(9,26)+=gauss_weight*(DN_v(3,0)*crLHS292 + DN_v(3,1)*crLHS294 + DN_v(3,2)*crLHS296 - crLHS298*crLHS895 - crLHS298*crLHS897 + crLHS929); + rLHS(9,27)+=gauss_weight*(DN_v(3,0)*crLHS299 + DN_v(3,1)*crLHS301 + DN_v(3,2)*crLHS303 - crLHS311*crLHS895 - crLHS311*crLHS897 + crLHS930 + crLHS932); + rLHS(9,28)+=gauss_weight*(DN_v(3,0)*crLHS314 + DN_v(3,1)*crLHS316 + DN_v(3,2)*crLHS319 - crLHS322*crLHS895 - crLHS322*crLHS897 + crLHS933); + rLHS(9,29)+=gauss_weight*(DN_v(3,0)*crLHS323 + DN_v(3,1)*crLHS325 + DN_v(3,2)*crLHS327 - crLHS329*crLHS895 - crLHS329*crLHS897 + crLHS934); + rLHS(9,30)+=gauss_weight*(crLHS117*crLHS331 + crLHS331*crLHS896 + crLHS935); + rLHS(9,31)+=gauss_weight*(crLHS117*crLHS333 + crLHS333*crLHS896 + crLHS936); + rLHS(9,32)+=gauss_weight*(crLHS117*crLHS335 + crLHS335*crLHS896 + crLHS937); + rLHS(9,33)+=gauss_weight*(crLHS117*crLHS337 + crLHS337*crLHS896 + crLHS938); + rLHS(10,0)+=gauss_weight*(DN_v(3,0)*crLHS2 + DN_v(3,1)*crLHS338 + DN_v(3,2)*crLHS339 + crLHS129 - crLHS342*crLHS895 - crLHS342*crLHS897); + rLHS(10,1)+=gauss_weight*(DN_v(3,0)*crLHS28 + DN_v(3,1)*crLHS343 + DN_v(3,2)*crLHS345 - crLHS350*crLHS895 - crLHS350*crLHS897 + crLHS404 + crLHS898); + rLHS(10,2)+=gauss_weight*(DN_v(3,0)*crLHS38 + DN_v(3,1)*crLHS351 + DN_v(3,2)*crLHS353 - crLHS356*crLHS895 - crLHS356*crLHS897 + crLHS583); + rLHS(10,3)+=gauss_weight*(DN_v(3,0)*crLHS45 + DN_v(3,1)*crLHS357 + DN_v(3,2)*crLHS358 - crLHS362*crLHS895 - crLHS362*crLHS897 + crLHS699); + rLHS(10,4)+=gauss_weight*(DN_v(3,0)*crLHS61 + DN_v(3,1)*crLHS363 + DN_v(3,2)*crLHS365 - crLHS370*crLHS895 - crLHS370*crLHS897 + crLHS741 + crLHS899); + rLHS(10,5)+=gauss_weight*(DN_v(3,0)*crLHS70 + DN_v(3,1)*crLHS371 + DN_v(3,2)*crLHS373 - crLHS375*crLHS895 - crLHS375*crLHS897 + crLHS770); + rLHS(10,6)+=gauss_weight*(DN_v(3,0)*crLHS77 + DN_v(3,1)*crLHS376 + DN_v(3,2)*crLHS377 - crLHS381*crLHS895 - crLHS381*crLHS897 + crLHS806); + rLHS(10,7)+=gauss_weight*(DN_v(3,0)*crLHS93 + DN_v(3,1)*crLHS382 + DN_v(3,2)*crLHS384 - crLHS389*crLHS895 - crLHS389*crLHS897 + crLHS845 + crLHS900); + rLHS(10,8)+=gauss_weight*(DN_v(3,0)*crLHS102 + DN_v(3,1)*crLHS390 + DN_v(3,2)*crLHS392 - crLHS394*crLHS895 - crLHS394*crLHS897 + crLHS871); + rLHS(10,9)+=gauss_weight*(DN_v(3,0)*crLHS109 + DN_v(3,1)*crLHS395 + DN_v(3,2)*crLHS396 - crLHS400*crLHS895 - crLHS400*crLHS897 + crLHS903); + rLHS(10,10)+=gauss_weight*(DN_v(3,0)*crLHS125 + std::pow(DN_v(3,1), 2)*crLHS9 + DN_v(3,1)*crLHS401 + DN_v(3,2)*crLHS403 - crLHS408*crLHS895 - crLHS408*crLHS897 + crLHS901); + rLHS(10,11)+=gauss_weight*(DN_v(3,0)*crLHS134 + DN_v(3,1)*crLHS409 + DN_v(3,2)*crLHS411 - crLHS413*crLHS895 - crLHS413*crLHS897 + crLHS940); + rLHS(10,12)+=gauss_weight*(DN_v(3,0)*crLHS141 + DN_v(3,1)*crLHS414 + DN_v(3,2)*crLHS415 - crLHS419*crLHS895 - crLHS419*crLHS897 + crLHS941); + rLHS(10,13)+=gauss_weight*(DN_v(3,0)*crLHS157 + DN_v(3,1)*crLHS420 + DN_v(3,2)*crLHS422 - crLHS427*crLHS895 - crLHS427*crLHS897 + crLHS907 + crLHS942); + rLHS(10,14)+=gauss_weight*(DN_v(3,0)*crLHS166 + DN_v(3,1)*crLHS428 + DN_v(3,2)*crLHS430 - crLHS432*crLHS895 - crLHS432*crLHS897 + crLHS943); + rLHS(10,15)+=gauss_weight*(DN_v(3,0)*crLHS173 + DN_v(3,1)*crLHS433 + DN_v(3,2)*crLHS434 - crLHS438*crLHS895 - crLHS438*crLHS897 + crLHS944); + rLHS(10,16)+=gauss_weight*(DN_v(3,0)*crLHS189 + DN_v(3,1)*crLHS439 + DN_v(3,2)*crLHS441 - crLHS446*crLHS895 - crLHS446*crLHS897 + crLHS912 + crLHS945); + rLHS(10,17)+=gauss_weight*(DN_v(3,0)*crLHS198 + DN_v(3,1)*crLHS447 + DN_v(3,2)*crLHS449 - crLHS451*crLHS895 - crLHS451*crLHS897 + crLHS946); + rLHS(10,18)+=gauss_weight*(DN_v(3,0)*crLHS205 + DN_v(3,1)*crLHS452 + DN_v(3,2)*crLHS453 - crLHS457*crLHS895 - crLHS457*crLHS897 + crLHS947); + rLHS(10,19)+=gauss_weight*(DN_v(3,0)*crLHS221 + DN_v(3,1)*crLHS458 + DN_v(3,2)*crLHS460 - crLHS465*crLHS895 - crLHS465*crLHS897 + crLHS917 + crLHS948); + rLHS(10,20)+=gauss_weight*(DN_v(3,0)*crLHS230 + DN_v(3,1)*crLHS466 + DN_v(3,2)*crLHS468 - crLHS470*crLHS895 - crLHS470*crLHS897 + crLHS949); + rLHS(10,21)+=gauss_weight*(DN_v(3,0)*crLHS237 + DN_v(3,1)*crLHS471 + DN_v(3,2)*crLHS472 - crLHS476*crLHS895 - crLHS476*crLHS897 + crLHS950); + rLHS(10,22)+=gauss_weight*(DN_v(3,0)*crLHS253 + DN_v(3,1)*crLHS477 + DN_v(3,2)*crLHS479 - crLHS484*crLHS895 - crLHS484*crLHS897 + crLHS922 + crLHS951); + rLHS(10,23)+=gauss_weight*(DN_v(3,0)*crLHS262 + DN_v(3,1)*crLHS485 + DN_v(3,2)*crLHS487 - crLHS489*crLHS895 - crLHS489*crLHS897 + crLHS952); + rLHS(10,24)+=gauss_weight*(DN_v(3,0)*crLHS269 + DN_v(3,1)*crLHS490 + DN_v(3,2)*crLHS491 - crLHS495*crLHS895 - crLHS495*crLHS897 + crLHS953); + rLHS(10,25)+=gauss_weight*(DN_v(3,0)*crLHS285 + DN_v(3,1)*crLHS496 + DN_v(3,2)*crLHS498 - crLHS503*crLHS895 - crLHS503*crLHS897 + crLHS927 + crLHS954); + rLHS(10,26)+=gauss_weight*(DN_v(3,0)*crLHS294 + DN_v(3,1)*crLHS504 + DN_v(3,2)*crLHS506 - crLHS508*crLHS895 - crLHS508*crLHS897 + crLHS955); + rLHS(10,27)+=gauss_weight*(DN_v(3,0)*crLHS301 + DN_v(3,1)*crLHS509 + DN_v(3,2)*crLHS510 - crLHS514*crLHS895 - crLHS514*crLHS897 + crLHS956); + rLHS(10,28)+=gauss_weight*(DN_v(3,0)*crLHS316 + DN_v(3,1)*crLHS515 + DN_v(3,2)*crLHS517 - crLHS522*crLHS895 - crLHS522*crLHS897 + crLHS932 + crLHS957); + rLHS(10,29)+=gauss_weight*(DN_v(3,0)*crLHS325 + DN_v(3,1)*crLHS523 + DN_v(3,2)*crLHS525 - crLHS527*crLHS895 - crLHS527*crLHS897 + crLHS958); + rLHS(10,30)+=gauss_weight*(crLHS117*crLHS529 + crLHS529*crLHS896 + crLHS959); + rLHS(10,31)+=gauss_weight*(crLHS117*crLHS531 + crLHS531*crLHS896 + crLHS960); + rLHS(10,32)+=gauss_weight*(crLHS117*crLHS533 + crLHS533*crLHS896 + crLHS961); + rLHS(10,33)+=gauss_weight*(crLHS117*crLHS535 + crLHS535*crLHS896 + crLHS962); + rLHS(11,0)+=gauss_weight*(DN_v(3,0)*crLHS4 + DN_v(3,1)*crLHS339 + DN_v(3,2)*crLHS536 + crLHS137 - crLHS539*crLHS895 - crLHS539*crLHS897); + rLHS(11,1)+=gauss_weight*(DN_v(3,0)*crLHS31 + DN_v(3,1)*crLHS345 + DN_v(3,2)*crLHS540 + crLHS412 - crLHS542*crLHS895 - crLHS542*crLHS897); + rLHS(11,2)+=gauss_weight*(DN_v(3,0)*crLHS40 + DN_v(3,1)*crLHS353 + DN_v(3,2)*crLHS543 - crLHS547*crLHS895 - crLHS547*crLHS897 + crLHS587 + crLHS898); + rLHS(11,3)+=gauss_weight*(DN_v(3,0)*crLHS47 + DN_v(3,1)*crLHS358 + DN_v(3,2)*crLHS548 - crLHS553*crLHS895 - crLHS553*crLHS897 + crLHS700); + rLHS(11,4)+=gauss_weight*(DN_v(3,0)*crLHS64 + DN_v(3,1)*crLHS365 + DN_v(3,2)*crLHS554 - crLHS557*crLHS895 - crLHS557*crLHS897 + crLHS742); + rLHS(11,5)+=gauss_weight*(DN_v(3,0)*crLHS72 + DN_v(3,1)*crLHS373 + DN_v(3,2)*crLHS558 - crLHS562*crLHS895 - crLHS562*crLHS897 + crLHS771 + crLHS899); + rLHS(11,6)+=gauss_weight*(DN_v(3,0)*crLHS79 + DN_v(3,1)*crLHS377 + DN_v(3,2)*crLHS563 - crLHS567*crLHS895 - crLHS567*crLHS897 + crLHS807); + rLHS(11,7)+=gauss_weight*(DN_v(3,0)*crLHS96 + DN_v(3,1)*crLHS384 + DN_v(3,2)*crLHS568 - crLHS571*crLHS895 - crLHS571*crLHS897 + crLHS846); + rLHS(11,8)+=gauss_weight*(DN_v(3,0)*crLHS104 + DN_v(3,1)*crLHS392 + DN_v(3,2)*crLHS572 - crLHS576*crLHS895 - crLHS576*crLHS897 + crLHS872 + crLHS900); + rLHS(11,9)+=gauss_weight*(DN_v(3,0)*crLHS111 + DN_v(3,1)*crLHS396 + DN_v(3,2)*crLHS577 - crLHS581*crLHS895 - crLHS581*crLHS897 + crLHS904); + rLHS(11,10)+=gauss_weight*(DN_v(3,0)*crLHS128 + DN_v(3,1)*crLHS403 + DN_v(3,2)*crLHS582 - crLHS585*crLHS895 - crLHS585*crLHS897 + crLHS940); + rLHS(11,11)+=gauss_weight*(DN_v(3,0)*crLHS136 + DN_v(3,1)*crLHS411 + std::pow(DN_v(3,2), 2)*crLHS9 + DN_v(3,2)*crLHS586 - crLHS590*crLHS895 - crLHS590*crLHS897 + crLHS901); + rLHS(11,12)+=gauss_weight*(DN_v(3,0)*crLHS143 + DN_v(3,1)*crLHS415 + DN_v(3,2)*crLHS591 - crLHS595*crLHS895 - crLHS595*crLHS897 + crLHS964); + rLHS(11,13)+=gauss_weight*(DN_v(3,0)*crLHS160 + DN_v(3,1)*crLHS422 + DN_v(3,2)*crLHS596 - crLHS599*crLHS895 - crLHS599*crLHS897 + crLHS965); + rLHS(11,14)+=gauss_weight*(DN_v(3,0)*crLHS168 + DN_v(3,1)*crLHS430 + DN_v(3,2)*crLHS600 - crLHS604*crLHS895 - crLHS604*crLHS897 + crLHS907 + crLHS966); + rLHS(11,15)+=gauss_weight*(DN_v(3,0)*crLHS175 + DN_v(3,1)*crLHS434 + DN_v(3,2)*crLHS605 - crLHS609*crLHS895 - crLHS609*crLHS897 + crLHS967); + rLHS(11,16)+=gauss_weight*(DN_v(3,0)*crLHS192 + DN_v(3,1)*crLHS441 + DN_v(3,2)*crLHS610 - crLHS613*crLHS895 - crLHS613*crLHS897 + crLHS968); + rLHS(11,17)+=gauss_weight*(DN_v(3,0)*crLHS200 + DN_v(3,1)*crLHS449 + DN_v(3,2)*crLHS614 - crLHS618*crLHS895 - crLHS618*crLHS897 + crLHS912 + crLHS969); + rLHS(11,18)+=gauss_weight*(DN_v(3,0)*crLHS207 + DN_v(3,1)*crLHS453 + DN_v(3,2)*crLHS619 - crLHS623*crLHS895 - crLHS623*crLHS897 + crLHS970); + rLHS(11,19)+=gauss_weight*(DN_v(3,0)*crLHS224 + DN_v(3,1)*crLHS460 + DN_v(3,2)*crLHS624 - crLHS627*crLHS895 - crLHS627*crLHS897 + crLHS971); + rLHS(11,20)+=gauss_weight*(DN_v(3,0)*crLHS232 + DN_v(3,1)*crLHS468 + DN_v(3,2)*crLHS628 - crLHS632*crLHS895 - crLHS632*crLHS897 + crLHS917 + crLHS972); + rLHS(11,21)+=gauss_weight*(DN_v(3,0)*crLHS239 + DN_v(3,1)*crLHS472 + DN_v(3,2)*crLHS633 - crLHS637*crLHS895 - crLHS637*crLHS897 + crLHS973); + rLHS(11,22)+=gauss_weight*(DN_v(3,0)*crLHS256 + DN_v(3,1)*crLHS479 + DN_v(3,2)*crLHS638 - crLHS641*crLHS895 - crLHS641*crLHS897 + crLHS974); + rLHS(11,23)+=gauss_weight*(DN_v(3,0)*crLHS264 + DN_v(3,1)*crLHS487 + DN_v(3,2)*crLHS642 - crLHS646*crLHS895 - crLHS646*crLHS897 + crLHS922 + crLHS975); + rLHS(11,24)+=gauss_weight*(DN_v(3,0)*crLHS271 + DN_v(3,1)*crLHS491 + DN_v(3,2)*crLHS647 - crLHS651*crLHS895 - crLHS651*crLHS897 + crLHS976); + rLHS(11,25)+=gauss_weight*(DN_v(3,0)*crLHS288 + DN_v(3,1)*crLHS498 + DN_v(3,2)*crLHS652 - crLHS655*crLHS895 - crLHS655*crLHS897 + crLHS977); + rLHS(11,26)+=gauss_weight*(DN_v(3,0)*crLHS296 + DN_v(3,1)*crLHS506 + DN_v(3,2)*crLHS656 - crLHS660*crLHS895 - crLHS660*crLHS897 + crLHS927 + crLHS978); + rLHS(11,27)+=gauss_weight*(DN_v(3,0)*crLHS303 + DN_v(3,1)*crLHS510 + DN_v(3,2)*crLHS661 - crLHS665*crLHS895 - crLHS665*crLHS897 + crLHS979); + rLHS(11,28)+=gauss_weight*(DN_v(3,0)*crLHS319 + DN_v(3,1)*crLHS517 + DN_v(3,2)*crLHS666 - crLHS669*crLHS895 - crLHS669*crLHS897 + crLHS980); + rLHS(11,29)+=gauss_weight*(DN_v(3,0)*crLHS327 + DN_v(3,1)*crLHS525 + DN_v(3,2)*crLHS670 - crLHS674*crLHS895 - crLHS674*crLHS897 + crLHS932 + crLHS981); + rLHS(11,30)+=gauss_weight*(crLHS117*crLHS676 + crLHS676*crLHS896 + crLHS982); + rLHS(11,31)+=gauss_weight*(crLHS117*crLHS678 + crLHS678*crLHS896 + crLHS983); + rLHS(11,32)+=gauss_weight*(crLHS117*crLHS680 + crLHS680*crLHS896 + crLHS984); + rLHS(11,33)+=gauss_weight*(crLHS117*crLHS682 + crLHS682*crLHS896 + crLHS985); + rLHS(12,0)+=gauss_weight*(DN_v(4,0)*crLHS0 + DN_v(4,1)*crLHS2 + DN_v(4,2)*crLHS4 + crLHS144 - crLHS19*crLHS986 - crLHS19*crLHS988 + crLHS989); + rLHS(12,1)+=gauss_weight*(DN_v(4,0)*crLHS26 + DN_v(4,1)*crLHS28 + DN_v(4,2)*crLHS31 - crLHS35*crLHS986 - crLHS35*crLHS988 + crLHS416); + rLHS(12,2)+=gauss_weight*(DN_v(4,0)*crLHS36 + DN_v(4,1)*crLHS38 + DN_v(4,2)*crLHS40 - crLHS42*crLHS986 - crLHS42*crLHS988 + crLHS592); + rLHS(12,3)+=gauss_weight*(DN_v(4,0)*crLHS43 + DN_v(4,1)*crLHS45 + DN_v(4,2)*crLHS47 - crLHS56*crLHS986 - crLHS56*crLHS988 + crLHS701 + crLHS990); + rLHS(12,4)+=gauss_weight*(DN_v(4,0)*crLHS59 + DN_v(4,1)*crLHS61 + DN_v(4,2)*crLHS64 - crLHS67*crLHS986 - crLHS67*crLHS988 + crLHS743); + rLHS(12,5)+=gauss_weight*(DN_v(4,0)*crLHS68 + DN_v(4,1)*crLHS70 + DN_v(4,2)*crLHS72 - crLHS74*crLHS986 - crLHS74*crLHS988 + crLHS772); + rLHS(12,6)+=gauss_weight*(DN_v(4,0)*crLHS75 + DN_v(4,1)*crLHS77 + DN_v(4,2)*crLHS79 + crLHS808 - crLHS88*crLHS986 - crLHS88*crLHS988 + crLHS991); + rLHS(12,7)+=gauss_weight*(DN_v(4,0)*crLHS91 + DN_v(4,1)*crLHS93 + DN_v(4,2)*crLHS96 + crLHS847 - crLHS986*crLHS99 - crLHS988*crLHS99); + rLHS(12,8)+=gauss_weight*(DN_v(4,0)*crLHS100 + DN_v(4,1)*crLHS102 + DN_v(4,2)*crLHS104 - crLHS106*crLHS986 - crLHS106*crLHS988 + crLHS873); + rLHS(12,9)+=gauss_weight*(DN_v(4,0)*crLHS107 + DN_v(4,1)*crLHS109 + DN_v(4,2)*crLHS111 - crLHS120*crLHS986 - crLHS120*crLHS988 + crLHS905 + crLHS992); + rLHS(12,10)+=gauss_weight*(DN_v(4,0)*crLHS123 + DN_v(4,1)*crLHS125 + DN_v(4,2)*crLHS128 - crLHS131*crLHS986 - crLHS131*crLHS988 + crLHS941); + rLHS(12,11)+=gauss_weight*(DN_v(4,0)*crLHS132 + DN_v(4,1)*crLHS134 + DN_v(4,2)*crLHS136 - crLHS138*crLHS986 - crLHS138*crLHS988 + crLHS964); + rLHS(12,12)+=gauss_weight*(std::pow(DN_v(4,0), 2)*crLHS9 + DN_v(4,0)*crLHS139 + DN_v(4,1)*crLHS141 + DN_v(4,2)*crLHS143 - crLHS152*crLHS986 - crLHS152*crLHS988 + crLHS993); + rLHS(12,13)+=gauss_weight*(DN_v(4,0)*crLHS155 + DN_v(4,1)*crLHS157 + DN_v(4,2)*crLHS160 - crLHS163*crLHS986 - crLHS163*crLHS988 + crLHS995); + rLHS(12,14)+=gauss_weight*(DN_v(4,0)*crLHS164 + DN_v(4,1)*crLHS166 + DN_v(4,2)*crLHS168 - crLHS170*crLHS986 - crLHS170*crLHS988 + crLHS996); + rLHS(12,15)+=gauss_weight*(DN_v(4,0)*crLHS171 + DN_v(4,1)*crLHS173 + DN_v(4,2)*crLHS175 - crLHS184*crLHS986 - crLHS184*crLHS988 + crLHS997 + crLHS999); + rLHS(12,16)+=gauss_weight*(DN_v(4,0)*crLHS187 + DN_v(4,1)*crLHS189 + DN_v(4,2)*crLHS192 + crLHS1000 - crLHS195*crLHS986 - crLHS195*crLHS988); + rLHS(12,17)+=gauss_weight*(DN_v(4,0)*crLHS196 + DN_v(4,1)*crLHS198 + DN_v(4,2)*crLHS200 + crLHS1001 - crLHS202*crLHS986 - crLHS202*crLHS988); + rLHS(12,18)+=gauss_weight*(DN_v(4,0)*crLHS203 + DN_v(4,1)*crLHS205 + DN_v(4,2)*crLHS207 + crLHS1002 + crLHS1004 - crLHS216*crLHS986 - crLHS216*crLHS988); + rLHS(12,19)+=gauss_weight*(DN_v(4,0)*crLHS219 + DN_v(4,1)*crLHS221 + DN_v(4,2)*crLHS224 + crLHS1005 - crLHS227*crLHS986 - crLHS227*crLHS988); + rLHS(12,20)+=gauss_weight*(DN_v(4,0)*crLHS228 + DN_v(4,1)*crLHS230 + DN_v(4,2)*crLHS232 + crLHS1006 - crLHS234*crLHS986 - crLHS234*crLHS988); + rLHS(12,21)+=gauss_weight*(DN_v(4,0)*crLHS235 + DN_v(4,1)*crLHS237 + DN_v(4,2)*crLHS239 + crLHS1007 + crLHS1009 - crLHS248*crLHS986 - crLHS248*crLHS988); + rLHS(12,22)+=gauss_weight*(DN_v(4,0)*crLHS251 + DN_v(4,1)*crLHS253 + DN_v(4,2)*crLHS256 + crLHS1010 - crLHS259*crLHS986 - crLHS259*crLHS988); + rLHS(12,23)+=gauss_weight*(DN_v(4,0)*crLHS260 + DN_v(4,1)*crLHS262 + DN_v(4,2)*crLHS264 + crLHS1011 - crLHS266*crLHS986 - crLHS266*crLHS988); + rLHS(12,24)+=gauss_weight*(DN_v(4,0)*crLHS267 + DN_v(4,1)*crLHS269 + DN_v(4,2)*crLHS271 + crLHS1012 + crLHS1014 - crLHS280*crLHS986 - crLHS280*crLHS988); + rLHS(12,25)+=gauss_weight*(DN_v(4,0)*crLHS283 + DN_v(4,1)*crLHS285 + DN_v(4,2)*crLHS288 + crLHS1015 - crLHS291*crLHS986 - crLHS291*crLHS988); + rLHS(12,26)+=gauss_weight*(DN_v(4,0)*crLHS292 + DN_v(4,1)*crLHS294 + DN_v(4,2)*crLHS296 + crLHS1016 - crLHS298*crLHS986 - crLHS298*crLHS988); + rLHS(12,27)+=gauss_weight*(DN_v(4,0)*crLHS299 + DN_v(4,1)*crLHS301 + DN_v(4,2)*crLHS303 + crLHS1017 + crLHS1019 - crLHS311*crLHS986 - crLHS311*crLHS988); + rLHS(12,28)+=gauss_weight*(DN_v(4,0)*crLHS314 + DN_v(4,1)*crLHS316 + DN_v(4,2)*crLHS319 + crLHS1020 - crLHS322*crLHS986 - crLHS322*crLHS988); + rLHS(12,29)+=gauss_weight*(DN_v(4,0)*crLHS323 + DN_v(4,1)*crLHS325 + DN_v(4,2)*crLHS327 + crLHS1021 - crLHS329*crLHS986 - crLHS329*crLHS988); + rLHS(12,30)+=gauss_weight*(crLHS1022 + crLHS149*crLHS331 + crLHS331*crLHS987); + rLHS(12,31)+=gauss_weight*(crLHS1023 + crLHS149*crLHS333 + crLHS333*crLHS987); + rLHS(12,32)+=gauss_weight*(crLHS1024 + crLHS149*crLHS335 + crLHS335*crLHS987); + rLHS(12,33)+=gauss_weight*(crLHS1025 + crLHS149*crLHS337 + crLHS337*crLHS987); + rLHS(13,0)+=gauss_weight*(DN_v(4,0)*crLHS2 + DN_v(4,1)*crLHS338 + DN_v(4,2)*crLHS339 + crLHS161 - crLHS342*crLHS986 - crLHS342*crLHS988); + rLHS(13,1)+=gauss_weight*(DN_v(4,0)*crLHS28 + DN_v(4,1)*crLHS343 + DN_v(4,2)*crLHS345 - crLHS350*crLHS986 - crLHS350*crLHS988 + crLHS423 + crLHS989); + rLHS(13,2)+=gauss_weight*(DN_v(4,0)*crLHS38 + DN_v(4,1)*crLHS351 + DN_v(4,2)*crLHS353 - crLHS356*crLHS986 - crLHS356*crLHS988 + crLHS597); + rLHS(13,3)+=gauss_weight*(DN_v(4,0)*crLHS45 + DN_v(4,1)*crLHS357 + DN_v(4,2)*crLHS358 - crLHS362*crLHS986 - crLHS362*crLHS988 + crLHS704); + rLHS(13,4)+=gauss_weight*(DN_v(4,0)*crLHS61 + DN_v(4,1)*crLHS363 + DN_v(4,2)*crLHS365 - crLHS370*crLHS986 - crLHS370*crLHS988 + crLHS744 + crLHS990); + rLHS(13,5)+=gauss_weight*(DN_v(4,0)*crLHS70 + DN_v(4,1)*crLHS371 + DN_v(4,2)*crLHS373 - crLHS375*crLHS986 - crLHS375*crLHS988 + crLHS773); + rLHS(13,6)+=gauss_weight*(DN_v(4,0)*crLHS77 + DN_v(4,1)*crLHS376 + DN_v(4,2)*crLHS377 - crLHS381*crLHS986 - crLHS381*crLHS988 + crLHS811); + rLHS(13,7)+=gauss_weight*(DN_v(4,0)*crLHS93 + DN_v(4,1)*crLHS382 + DN_v(4,2)*crLHS384 - crLHS389*crLHS986 - crLHS389*crLHS988 + crLHS848 + crLHS991); + rLHS(13,8)+=gauss_weight*(DN_v(4,0)*crLHS102 + DN_v(4,1)*crLHS390 + DN_v(4,2)*crLHS392 - crLHS394*crLHS986 - crLHS394*crLHS988 + crLHS874); + rLHS(13,9)+=gauss_weight*(DN_v(4,0)*crLHS109 + DN_v(4,1)*crLHS395 + DN_v(4,2)*crLHS396 - crLHS400*crLHS986 - crLHS400*crLHS988 + crLHS908); + rLHS(13,10)+=gauss_weight*(DN_v(4,0)*crLHS125 + DN_v(4,1)*crLHS401 + DN_v(4,2)*crLHS403 - crLHS408*crLHS986 - crLHS408*crLHS988 + crLHS942 + crLHS992); + rLHS(13,11)+=gauss_weight*(DN_v(4,0)*crLHS134 + DN_v(4,1)*crLHS409 + DN_v(4,2)*crLHS411 - crLHS413*crLHS986 - crLHS413*crLHS988 + crLHS965); + rLHS(13,12)+=gauss_weight*(DN_v(4,0)*crLHS141 + DN_v(4,1)*crLHS414 + DN_v(4,2)*crLHS415 - crLHS419*crLHS986 - crLHS419*crLHS988 + crLHS995); + rLHS(13,13)+=gauss_weight*(DN_v(4,0)*crLHS157 + std::pow(DN_v(4,1), 2)*crLHS9 + DN_v(4,1)*crLHS420 + DN_v(4,2)*crLHS422 - crLHS427*crLHS986 - crLHS427*crLHS988 + crLHS993); + rLHS(13,14)+=gauss_weight*(DN_v(4,0)*crLHS166 + DN_v(4,1)*crLHS428 + DN_v(4,2)*crLHS430 + crLHS1027 - crLHS432*crLHS986 - crLHS432*crLHS988); + rLHS(13,15)+=gauss_weight*(DN_v(4,0)*crLHS173 + DN_v(4,1)*crLHS433 + DN_v(4,2)*crLHS434 + crLHS1028 - crLHS438*crLHS986 - crLHS438*crLHS988); + rLHS(13,16)+=gauss_weight*(DN_v(4,0)*crLHS189 + DN_v(4,1)*crLHS439 + DN_v(4,2)*crLHS441 + crLHS1029 - crLHS446*crLHS986 - crLHS446*crLHS988 + crLHS999); + rLHS(13,17)+=gauss_weight*(DN_v(4,0)*crLHS198 + DN_v(4,1)*crLHS447 + DN_v(4,2)*crLHS449 + crLHS1030 - crLHS451*crLHS986 - crLHS451*crLHS988); + rLHS(13,18)+=gauss_weight*(DN_v(4,0)*crLHS205 + DN_v(4,1)*crLHS452 + DN_v(4,2)*crLHS453 + crLHS1031 - crLHS457*crLHS986 - crLHS457*crLHS988); + rLHS(13,19)+=gauss_weight*(DN_v(4,0)*crLHS221 + DN_v(4,1)*crLHS458 + DN_v(4,2)*crLHS460 + crLHS1004 + crLHS1032 - crLHS465*crLHS986 - crLHS465*crLHS988); + rLHS(13,20)+=gauss_weight*(DN_v(4,0)*crLHS230 + DN_v(4,1)*crLHS466 + DN_v(4,2)*crLHS468 + crLHS1033 - crLHS470*crLHS986 - crLHS470*crLHS988); + rLHS(13,21)+=gauss_weight*(DN_v(4,0)*crLHS237 + DN_v(4,1)*crLHS471 + DN_v(4,2)*crLHS472 + crLHS1034 - crLHS476*crLHS986 - crLHS476*crLHS988); + rLHS(13,22)+=gauss_weight*(DN_v(4,0)*crLHS253 + DN_v(4,1)*crLHS477 + DN_v(4,2)*crLHS479 + crLHS1009 + crLHS1035 - crLHS484*crLHS986 - crLHS484*crLHS988); + rLHS(13,23)+=gauss_weight*(DN_v(4,0)*crLHS262 + DN_v(4,1)*crLHS485 + DN_v(4,2)*crLHS487 + crLHS1036 - crLHS489*crLHS986 - crLHS489*crLHS988); + rLHS(13,24)+=gauss_weight*(DN_v(4,0)*crLHS269 + DN_v(4,1)*crLHS490 + DN_v(4,2)*crLHS491 + crLHS1037 - crLHS495*crLHS986 - crLHS495*crLHS988); + rLHS(13,25)+=gauss_weight*(DN_v(4,0)*crLHS285 + DN_v(4,1)*crLHS496 + DN_v(4,2)*crLHS498 + crLHS1014 + crLHS1038 - crLHS503*crLHS986 - crLHS503*crLHS988); + rLHS(13,26)+=gauss_weight*(DN_v(4,0)*crLHS294 + DN_v(4,1)*crLHS504 + DN_v(4,2)*crLHS506 + crLHS1039 - crLHS508*crLHS986 - crLHS508*crLHS988); + rLHS(13,27)+=gauss_weight*(DN_v(4,0)*crLHS301 + DN_v(4,1)*crLHS509 + DN_v(4,2)*crLHS510 + crLHS1040 - crLHS514*crLHS986 - crLHS514*crLHS988); + rLHS(13,28)+=gauss_weight*(DN_v(4,0)*crLHS316 + DN_v(4,1)*crLHS515 + DN_v(4,2)*crLHS517 + crLHS1019 + crLHS1041 - crLHS522*crLHS986 - crLHS522*crLHS988); + rLHS(13,29)+=gauss_weight*(DN_v(4,0)*crLHS325 + DN_v(4,1)*crLHS523 + DN_v(4,2)*crLHS525 + crLHS1042 - crLHS527*crLHS986 - crLHS527*crLHS988); + rLHS(13,30)+=gauss_weight*(crLHS1043 + crLHS149*crLHS529 + crLHS529*crLHS987); + rLHS(13,31)+=gauss_weight*(crLHS1044 + crLHS149*crLHS531 + crLHS531*crLHS987); + rLHS(13,32)+=gauss_weight*(crLHS1045 + crLHS149*crLHS533 + crLHS533*crLHS987); + rLHS(13,33)+=gauss_weight*(crLHS1046 + crLHS149*crLHS535 + crLHS535*crLHS987); + rLHS(14,0)+=gauss_weight*(DN_v(4,0)*crLHS4 + DN_v(4,1)*crLHS339 + DN_v(4,2)*crLHS536 + crLHS169 - crLHS539*crLHS986 - crLHS539*crLHS988); + rLHS(14,1)+=gauss_weight*(DN_v(4,0)*crLHS31 + DN_v(4,1)*crLHS345 + DN_v(4,2)*crLHS540 + crLHS431 - crLHS542*crLHS986 - crLHS542*crLHS988); + rLHS(14,2)+=gauss_weight*(DN_v(4,0)*crLHS40 + DN_v(4,1)*crLHS353 + DN_v(4,2)*crLHS543 - crLHS547*crLHS986 - crLHS547*crLHS988 + crLHS601 + crLHS989); + rLHS(14,3)+=gauss_weight*(DN_v(4,0)*crLHS47 + DN_v(4,1)*crLHS358 + DN_v(4,2)*crLHS548 - crLHS553*crLHS986 - crLHS553*crLHS988 + crLHS705); + rLHS(14,4)+=gauss_weight*(DN_v(4,0)*crLHS64 + DN_v(4,1)*crLHS365 + DN_v(4,2)*crLHS554 - crLHS557*crLHS986 - crLHS557*crLHS988 + crLHS745); + rLHS(14,5)+=gauss_weight*(DN_v(4,0)*crLHS72 + DN_v(4,1)*crLHS373 + DN_v(4,2)*crLHS558 - crLHS562*crLHS986 - crLHS562*crLHS988 + crLHS774 + crLHS990); + rLHS(14,6)+=gauss_weight*(DN_v(4,0)*crLHS79 + DN_v(4,1)*crLHS377 + DN_v(4,2)*crLHS563 - crLHS567*crLHS986 - crLHS567*crLHS988 + crLHS812); + rLHS(14,7)+=gauss_weight*(DN_v(4,0)*crLHS96 + DN_v(4,1)*crLHS384 + DN_v(4,2)*crLHS568 - crLHS571*crLHS986 - crLHS571*crLHS988 + crLHS849); + rLHS(14,8)+=gauss_weight*(DN_v(4,0)*crLHS104 + DN_v(4,1)*crLHS392 + DN_v(4,2)*crLHS572 - crLHS576*crLHS986 - crLHS576*crLHS988 + crLHS875 + crLHS991); + rLHS(14,9)+=gauss_weight*(DN_v(4,0)*crLHS111 + DN_v(4,1)*crLHS396 + DN_v(4,2)*crLHS577 - crLHS581*crLHS986 - crLHS581*crLHS988 + crLHS909); + rLHS(14,10)+=gauss_weight*(DN_v(4,0)*crLHS128 + DN_v(4,1)*crLHS403 + DN_v(4,2)*crLHS582 - crLHS585*crLHS986 - crLHS585*crLHS988 + crLHS943); + rLHS(14,11)+=gauss_weight*(DN_v(4,0)*crLHS136 + DN_v(4,1)*crLHS411 + DN_v(4,2)*crLHS586 - crLHS590*crLHS986 - crLHS590*crLHS988 + crLHS966 + crLHS992); + rLHS(14,12)+=gauss_weight*(DN_v(4,0)*crLHS143 + DN_v(4,1)*crLHS415 + DN_v(4,2)*crLHS591 - crLHS595*crLHS986 - crLHS595*crLHS988 + crLHS996); + rLHS(14,13)+=gauss_weight*(DN_v(4,0)*crLHS160 + DN_v(4,1)*crLHS422 + DN_v(4,2)*crLHS596 + crLHS1027 - crLHS599*crLHS986 - crLHS599*crLHS988); + rLHS(14,14)+=gauss_weight*(DN_v(4,0)*crLHS168 + DN_v(4,1)*crLHS430 + std::pow(DN_v(4,2), 2)*crLHS9 + DN_v(4,2)*crLHS600 - crLHS604*crLHS986 - crLHS604*crLHS988 + crLHS993); + rLHS(14,15)+=gauss_weight*(DN_v(4,0)*crLHS175 + DN_v(4,1)*crLHS434 + DN_v(4,2)*crLHS605 + crLHS1048 - crLHS609*crLHS986 - crLHS609*crLHS988); + rLHS(14,16)+=gauss_weight*(DN_v(4,0)*crLHS192 + DN_v(4,1)*crLHS441 + DN_v(4,2)*crLHS610 + crLHS1049 - crLHS613*crLHS986 - crLHS613*crLHS988); + rLHS(14,17)+=gauss_weight*(DN_v(4,0)*crLHS200 + DN_v(4,1)*crLHS449 + DN_v(4,2)*crLHS614 + crLHS1050 - crLHS618*crLHS986 - crLHS618*crLHS988 + crLHS999); + rLHS(14,18)+=gauss_weight*(DN_v(4,0)*crLHS207 + DN_v(4,1)*crLHS453 + DN_v(4,2)*crLHS619 + crLHS1051 - crLHS623*crLHS986 - crLHS623*crLHS988); + rLHS(14,19)+=gauss_weight*(DN_v(4,0)*crLHS224 + DN_v(4,1)*crLHS460 + DN_v(4,2)*crLHS624 + crLHS1052 - crLHS627*crLHS986 - crLHS627*crLHS988); + rLHS(14,20)+=gauss_weight*(DN_v(4,0)*crLHS232 + DN_v(4,1)*crLHS468 + DN_v(4,2)*crLHS628 + crLHS1004 + crLHS1053 - crLHS632*crLHS986 - crLHS632*crLHS988); + rLHS(14,21)+=gauss_weight*(DN_v(4,0)*crLHS239 + DN_v(4,1)*crLHS472 + DN_v(4,2)*crLHS633 + crLHS1054 - crLHS637*crLHS986 - crLHS637*crLHS988); + rLHS(14,22)+=gauss_weight*(DN_v(4,0)*crLHS256 + DN_v(4,1)*crLHS479 + DN_v(4,2)*crLHS638 + crLHS1055 - crLHS641*crLHS986 - crLHS641*crLHS988); + rLHS(14,23)+=gauss_weight*(DN_v(4,0)*crLHS264 + DN_v(4,1)*crLHS487 + DN_v(4,2)*crLHS642 + crLHS1009 + crLHS1056 - crLHS646*crLHS986 - crLHS646*crLHS988); + rLHS(14,24)+=gauss_weight*(DN_v(4,0)*crLHS271 + DN_v(4,1)*crLHS491 + DN_v(4,2)*crLHS647 + crLHS1057 - crLHS651*crLHS986 - crLHS651*crLHS988); + rLHS(14,25)+=gauss_weight*(DN_v(4,0)*crLHS288 + DN_v(4,1)*crLHS498 + DN_v(4,2)*crLHS652 + crLHS1058 - crLHS655*crLHS986 - crLHS655*crLHS988); + rLHS(14,26)+=gauss_weight*(DN_v(4,0)*crLHS296 + DN_v(4,1)*crLHS506 + DN_v(4,2)*crLHS656 + crLHS1014 + crLHS1059 - crLHS660*crLHS986 - crLHS660*crLHS988); + rLHS(14,27)+=gauss_weight*(DN_v(4,0)*crLHS303 + DN_v(4,1)*crLHS510 + DN_v(4,2)*crLHS661 + crLHS1060 - crLHS665*crLHS986 - crLHS665*crLHS988); + rLHS(14,28)+=gauss_weight*(DN_v(4,0)*crLHS319 + DN_v(4,1)*crLHS517 + DN_v(4,2)*crLHS666 + crLHS1061 - crLHS669*crLHS986 - crLHS669*crLHS988); + rLHS(14,29)+=gauss_weight*(DN_v(4,0)*crLHS327 + DN_v(4,1)*crLHS525 + DN_v(4,2)*crLHS670 + crLHS1019 + crLHS1062 - crLHS674*crLHS986 - crLHS674*crLHS988); + rLHS(14,30)+=gauss_weight*(crLHS1063 + crLHS149*crLHS676 + crLHS676*crLHS987); + rLHS(14,31)+=gauss_weight*(crLHS1064 + crLHS149*crLHS678 + crLHS678*crLHS987); + rLHS(14,32)+=gauss_weight*(crLHS1065 + crLHS149*crLHS680 + crLHS680*crLHS987); + rLHS(14,33)+=gauss_weight*(crLHS1066 + crLHS149*crLHS682 + crLHS682*crLHS987); + rLHS(15,0)+=gauss_weight*(DN_v(5,0)*crLHS0 + DN_v(5,1)*crLHS2 + DN_v(5,2)*crLHS4 - crLHS1067*crLHS19 - crLHS1069*crLHS19 + crLHS1070 + crLHS176); + rLHS(15,1)+=gauss_weight*(DN_v(5,0)*crLHS26 + DN_v(5,1)*crLHS28 + DN_v(5,2)*crLHS31 - crLHS1067*crLHS35 - crLHS1069*crLHS35 + crLHS435); + rLHS(15,2)+=gauss_weight*(DN_v(5,0)*crLHS36 + DN_v(5,1)*crLHS38 + DN_v(5,2)*crLHS40 - crLHS1067*crLHS42 - crLHS1069*crLHS42 + crLHS606); + rLHS(15,3)+=gauss_weight*(DN_v(5,0)*crLHS43 + DN_v(5,1)*crLHS45 + DN_v(5,2)*crLHS47 - crLHS1067*crLHS56 - crLHS1069*crLHS56 + crLHS1071 + crLHS706); + rLHS(15,4)+=gauss_weight*(DN_v(5,0)*crLHS59 + DN_v(5,1)*crLHS61 + DN_v(5,2)*crLHS64 - crLHS1067*crLHS67 - crLHS1069*crLHS67 + crLHS746); + rLHS(15,5)+=gauss_weight*(DN_v(5,0)*crLHS68 + DN_v(5,1)*crLHS70 + DN_v(5,2)*crLHS72 - crLHS1067*crLHS74 - crLHS1069*crLHS74 + crLHS775); + rLHS(15,6)+=gauss_weight*(DN_v(5,0)*crLHS75 + DN_v(5,1)*crLHS77 + DN_v(5,2)*crLHS79 - crLHS1067*crLHS88 - crLHS1069*crLHS88 + crLHS1072 + crLHS813); + rLHS(15,7)+=gauss_weight*(DN_v(5,0)*crLHS91 + DN_v(5,1)*crLHS93 + DN_v(5,2)*crLHS96 - crLHS1067*crLHS99 - crLHS1069*crLHS99 + crLHS850); + rLHS(15,8)+=gauss_weight*(DN_v(5,0)*crLHS100 + DN_v(5,1)*crLHS102 + DN_v(5,2)*crLHS104 - crLHS106*crLHS1067 - crLHS106*crLHS1069 + crLHS876); + rLHS(15,9)+=gauss_weight*(DN_v(5,0)*crLHS107 + DN_v(5,1)*crLHS109 + DN_v(5,2)*crLHS111 - crLHS1067*crLHS120 - crLHS1069*crLHS120 + crLHS1073 + crLHS910); + rLHS(15,10)+=gauss_weight*(DN_v(5,0)*crLHS123 + DN_v(5,1)*crLHS125 + DN_v(5,2)*crLHS128 - crLHS1067*crLHS131 - crLHS1069*crLHS131 + crLHS944); + rLHS(15,11)+=gauss_weight*(DN_v(5,0)*crLHS132 + DN_v(5,1)*crLHS134 + DN_v(5,2)*crLHS136 - crLHS1067*crLHS138 - crLHS1069*crLHS138 + crLHS967); + rLHS(15,12)+=gauss_weight*(DN_v(5,0)*crLHS139 + DN_v(5,1)*crLHS141 + DN_v(5,2)*crLHS143 - crLHS1067*crLHS152 - crLHS1069*crLHS152 + crLHS1074 + crLHS997); + rLHS(15,13)+=gauss_weight*(DN_v(5,0)*crLHS155 + DN_v(5,1)*crLHS157 + DN_v(5,2)*crLHS160 + crLHS1028 - crLHS1067*crLHS163 - crLHS1069*crLHS163); + rLHS(15,14)+=gauss_weight*(DN_v(5,0)*crLHS164 + DN_v(5,1)*crLHS166 + DN_v(5,2)*crLHS168 + crLHS1048 - crLHS1067*crLHS170 - crLHS1069*crLHS170); + rLHS(15,15)+=gauss_weight*(std::pow(DN_v(5,0), 2)*crLHS9 + DN_v(5,0)*crLHS171 + DN_v(5,1)*crLHS173 + DN_v(5,2)*crLHS175 - crLHS1067*crLHS184 - crLHS1069*crLHS184 + crLHS1075); + rLHS(15,16)+=gauss_weight*(DN_v(5,0)*crLHS187 + DN_v(5,1)*crLHS189 + DN_v(5,2)*crLHS192 - crLHS1067*crLHS195 - crLHS1069*crLHS195 + crLHS1077); + rLHS(15,17)+=gauss_weight*(DN_v(5,0)*crLHS196 + DN_v(5,1)*crLHS198 + DN_v(5,2)*crLHS200 - crLHS1067*crLHS202 - crLHS1069*crLHS202 + crLHS1078); + rLHS(15,18)+=gauss_weight*(DN_v(5,0)*crLHS203 + DN_v(5,1)*crLHS205 + DN_v(5,2)*crLHS207 - crLHS1067*crLHS216 - crLHS1069*crLHS216 + crLHS1079 + crLHS1081); + rLHS(15,19)+=gauss_weight*(DN_v(5,0)*crLHS219 + DN_v(5,1)*crLHS221 + DN_v(5,2)*crLHS224 - crLHS1067*crLHS227 - crLHS1069*crLHS227 + crLHS1082); + rLHS(15,20)+=gauss_weight*(DN_v(5,0)*crLHS228 + DN_v(5,1)*crLHS230 + DN_v(5,2)*crLHS232 - crLHS1067*crLHS234 - crLHS1069*crLHS234 + crLHS1083); + rLHS(15,21)+=gauss_weight*(DN_v(5,0)*crLHS235 + DN_v(5,1)*crLHS237 + DN_v(5,2)*crLHS239 - crLHS1067*crLHS248 - crLHS1069*crLHS248 + crLHS1084 + crLHS1086); + rLHS(15,22)+=gauss_weight*(DN_v(5,0)*crLHS251 + DN_v(5,1)*crLHS253 + DN_v(5,2)*crLHS256 - crLHS1067*crLHS259 - crLHS1069*crLHS259 + crLHS1087); + rLHS(15,23)+=gauss_weight*(DN_v(5,0)*crLHS260 + DN_v(5,1)*crLHS262 + DN_v(5,2)*crLHS264 - crLHS1067*crLHS266 - crLHS1069*crLHS266 + crLHS1088); + rLHS(15,24)+=gauss_weight*(DN_v(5,0)*crLHS267 + DN_v(5,1)*crLHS269 + DN_v(5,2)*crLHS271 - crLHS1067*crLHS280 - crLHS1069*crLHS280 + crLHS1089 + crLHS1091); + rLHS(15,25)+=gauss_weight*(DN_v(5,0)*crLHS283 + DN_v(5,1)*crLHS285 + DN_v(5,2)*crLHS288 - crLHS1067*crLHS291 - crLHS1069*crLHS291 + crLHS1092); + rLHS(15,26)+=gauss_weight*(DN_v(5,0)*crLHS292 + DN_v(5,1)*crLHS294 + DN_v(5,2)*crLHS296 - crLHS1067*crLHS298 - crLHS1069*crLHS298 + crLHS1093); + rLHS(15,27)+=gauss_weight*(DN_v(5,0)*crLHS299 + DN_v(5,1)*crLHS301 + DN_v(5,2)*crLHS303 - crLHS1067*crLHS311 - crLHS1069*crLHS311 + crLHS1094 + crLHS1096); + rLHS(15,28)+=gauss_weight*(DN_v(5,0)*crLHS314 + DN_v(5,1)*crLHS316 + DN_v(5,2)*crLHS319 - crLHS1067*crLHS322 - crLHS1069*crLHS322 + crLHS1097); + rLHS(15,29)+=gauss_weight*(DN_v(5,0)*crLHS323 + DN_v(5,1)*crLHS325 + DN_v(5,2)*crLHS327 - crLHS1067*crLHS329 - crLHS1069*crLHS329 + crLHS1098); + rLHS(15,30)+=gauss_weight*(crLHS1068*crLHS331 + crLHS1099 + crLHS181*crLHS331); + rLHS(15,31)+=gauss_weight*(crLHS1068*crLHS333 + crLHS1100 + crLHS181*crLHS333); + rLHS(15,32)+=gauss_weight*(crLHS1068*crLHS335 + crLHS1101 + crLHS181*crLHS335); + rLHS(15,33)+=gauss_weight*(crLHS1068*crLHS337 + crLHS1102 + crLHS181*crLHS337); + rLHS(16,0)+=gauss_weight*(DN_v(5,0)*crLHS2 + DN_v(5,1)*crLHS338 + DN_v(5,2)*crLHS339 - crLHS1067*crLHS342 - crLHS1069*crLHS342 + crLHS193); + rLHS(16,1)+=gauss_weight*(DN_v(5,0)*crLHS28 + DN_v(5,1)*crLHS343 + DN_v(5,2)*crLHS345 - crLHS1067*crLHS350 - crLHS1069*crLHS350 + crLHS1070 + crLHS442); + rLHS(16,2)+=gauss_weight*(DN_v(5,0)*crLHS38 + DN_v(5,1)*crLHS351 + DN_v(5,2)*crLHS353 - crLHS1067*crLHS356 - crLHS1069*crLHS356 + crLHS611); + rLHS(16,3)+=gauss_weight*(DN_v(5,0)*crLHS45 + DN_v(5,1)*crLHS357 + DN_v(5,2)*crLHS358 - crLHS1067*crLHS362 - crLHS1069*crLHS362 + crLHS709); + rLHS(16,4)+=gauss_weight*(DN_v(5,0)*crLHS61 + DN_v(5,1)*crLHS363 + DN_v(5,2)*crLHS365 - crLHS1067*crLHS370 - crLHS1069*crLHS370 + crLHS1071 + crLHS747); + rLHS(16,5)+=gauss_weight*(DN_v(5,0)*crLHS70 + DN_v(5,1)*crLHS371 + DN_v(5,2)*crLHS373 - crLHS1067*crLHS375 - crLHS1069*crLHS375 + crLHS776); + rLHS(16,6)+=gauss_weight*(DN_v(5,0)*crLHS77 + DN_v(5,1)*crLHS376 + DN_v(5,2)*crLHS377 - crLHS1067*crLHS381 - crLHS1069*crLHS381 + crLHS816); + rLHS(16,7)+=gauss_weight*(DN_v(5,0)*crLHS93 + DN_v(5,1)*crLHS382 + DN_v(5,2)*crLHS384 - crLHS1067*crLHS389 - crLHS1069*crLHS389 + crLHS1072 + crLHS851); + rLHS(16,8)+=gauss_weight*(DN_v(5,0)*crLHS102 + DN_v(5,1)*crLHS390 + DN_v(5,2)*crLHS392 - crLHS1067*crLHS394 - crLHS1069*crLHS394 + crLHS877); + rLHS(16,9)+=gauss_weight*(DN_v(5,0)*crLHS109 + DN_v(5,1)*crLHS395 + DN_v(5,2)*crLHS396 - crLHS1067*crLHS400 - crLHS1069*crLHS400 + crLHS913); + rLHS(16,10)+=gauss_weight*(DN_v(5,0)*crLHS125 + DN_v(5,1)*crLHS401 + DN_v(5,2)*crLHS403 - crLHS1067*crLHS408 - crLHS1069*crLHS408 + crLHS1073 + crLHS945); + rLHS(16,11)+=gauss_weight*(DN_v(5,0)*crLHS134 + DN_v(5,1)*crLHS409 + DN_v(5,2)*crLHS411 - crLHS1067*crLHS413 - crLHS1069*crLHS413 + crLHS968); + rLHS(16,12)+=gauss_weight*(DN_v(5,0)*crLHS141 + DN_v(5,1)*crLHS414 + DN_v(5,2)*crLHS415 + crLHS1000 - crLHS1067*crLHS419 - crLHS1069*crLHS419); + rLHS(16,13)+=gauss_weight*(DN_v(5,0)*crLHS157 + DN_v(5,1)*crLHS420 + DN_v(5,2)*crLHS422 + crLHS1029 - crLHS1067*crLHS427 - crLHS1069*crLHS427 + crLHS1074); + rLHS(16,14)+=gauss_weight*(DN_v(5,0)*crLHS166 + DN_v(5,1)*crLHS428 + DN_v(5,2)*crLHS430 + crLHS1049 - crLHS1067*crLHS432 - crLHS1069*crLHS432); + rLHS(16,15)+=gauss_weight*(DN_v(5,0)*crLHS173 + DN_v(5,1)*crLHS433 + DN_v(5,2)*crLHS434 - crLHS1067*crLHS438 - crLHS1069*crLHS438 + crLHS1077); + rLHS(16,16)+=gauss_weight*(DN_v(5,0)*crLHS189 + std::pow(DN_v(5,1), 2)*crLHS9 + DN_v(5,1)*crLHS439 + DN_v(5,2)*crLHS441 - crLHS1067*crLHS446 - crLHS1069*crLHS446 + crLHS1075); + rLHS(16,17)+=gauss_weight*(DN_v(5,0)*crLHS198 + DN_v(5,1)*crLHS447 + DN_v(5,2)*crLHS449 - crLHS1067*crLHS451 - crLHS1069*crLHS451 + crLHS1104); + rLHS(16,18)+=gauss_weight*(DN_v(5,0)*crLHS205 + DN_v(5,1)*crLHS452 + DN_v(5,2)*crLHS453 - crLHS1067*crLHS457 - crLHS1069*crLHS457 + crLHS1105); + rLHS(16,19)+=gauss_weight*(DN_v(5,0)*crLHS221 + DN_v(5,1)*crLHS458 + DN_v(5,2)*crLHS460 - crLHS1067*crLHS465 - crLHS1069*crLHS465 + crLHS1081 + crLHS1106); + rLHS(16,20)+=gauss_weight*(DN_v(5,0)*crLHS230 + DN_v(5,1)*crLHS466 + DN_v(5,2)*crLHS468 - crLHS1067*crLHS470 - crLHS1069*crLHS470 + crLHS1107); + rLHS(16,21)+=gauss_weight*(DN_v(5,0)*crLHS237 + DN_v(5,1)*crLHS471 + DN_v(5,2)*crLHS472 - crLHS1067*crLHS476 - crLHS1069*crLHS476 + crLHS1108); + rLHS(16,22)+=gauss_weight*(DN_v(5,0)*crLHS253 + DN_v(5,1)*crLHS477 + DN_v(5,2)*crLHS479 - crLHS1067*crLHS484 - crLHS1069*crLHS484 + crLHS1086 + crLHS1109); + rLHS(16,23)+=gauss_weight*(DN_v(5,0)*crLHS262 + DN_v(5,1)*crLHS485 + DN_v(5,2)*crLHS487 - crLHS1067*crLHS489 - crLHS1069*crLHS489 + crLHS1110); + rLHS(16,24)+=gauss_weight*(DN_v(5,0)*crLHS269 + DN_v(5,1)*crLHS490 + DN_v(5,2)*crLHS491 - crLHS1067*crLHS495 - crLHS1069*crLHS495 + crLHS1111); + rLHS(16,25)+=gauss_weight*(DN_v(5,0)*crLHS285 + DN_v(5,1)*crLHS496 + DN_v(5,2)*crLHS498 - crLHS1067*crLHS503 - crLHS1069*crLHS503 + crLHS1091 + crLHS1112); + rLHS(16,26)+=gauss_weight*(DN_v(5,0)*crLHS294 + DN_v(5,1)*crLHS504 + DN_v(5,2)*crLHS506 - crLHS1067*crLHS508 - crLHS1069*crLHS508 + crLHS1113); + rLHS(16,27)+=gauss_weight*(DN_v(5,0)*crLHS301 + DN_v(5,1)*crLHS509 + DN_v(5,2)*crLHS510 - crLHS1067*crLHS514 - crLHS1069*crLHS514 + crLHS1114); + rLHS(16,28)+=gauss_weight*(DN_v(5,0)*crLHS316 + DN_v(5,1)*crLHS515 + DN_v(5,2)*crLHS517 - crLHS1067*crLHS522 - crLHS1069*crLHS522 + crLHS1096 + crLHS1115); + rLHS(16,29)+=gauss_weight*(DN_v(5,0)*crLHS325 + DN_v(5,1)*crLHS523 + DN_v(5,2)*crLHS525 - crLHS1067*crLHS527 - crLHS1069*crLHS527 + crLHS1116); + rLHS(16,30)+=gauss_weight*(crLHS1068*crLHS529 + crLHS1117 + crLHS181*crLHS529); + rLHS(16,31)+=gauss_weight*(crLHS1068*crLHS531 + crLHS1118 + crLHS181*crLHS531); + rLHS(16,32)+=gauss_weight*(crLHS1068*crLHS533 + crLHS1119 + crLHS181*crLHS533); + rLHS(16,33)+=gauss_weight*(crLHS1068*crLHS535 + crLHS1120 + crLHS181*crLHS535); + rLHS(17,0)+=gauss_weight*(DN_v(5,0)*crLHS4 + DN_v(5,1)*crLHS339 + DN_v(5,2)*crLHS536 - crLHS1067*crLHS539 - crLHS1069*crLHS539 + crLHS201); + rLHS(17,1)+=gauss_weight*(DN_v(5,0)*crLHS31 + DN_v(5,1)*crLHS345 + DN_v(5,2)*crLHS540 - crLHS1067*crLHS542 - crLHS1069*crLHS542 + crLHS450); + rLHS(17,2)+=gauss_weight*(DN_v(5,0)*crLHS40 + DN_v(5,1)*crLHS353 + DN_v(5,2)*crLHS543 - crLHS1067*crLHS547 - crLHS1069*crLHS547 + crLHS1070 + crLHS615); + rLHS(17,3)+=gauss_weight*(DN_v(5,0)*crLHS47 + DN_v(5,1)*crLHS358 + DN_v(5,2)*crLHS548 - crLHS1067*crLHS553 - crLHS1069*crLHS553 + crLHS710); + rLHS(17,4)+=gauss_weight*(DN_v(5,0)*crLHS64 + DN_v(5,1)*crLHS365 + DN_v(5,2)*crLHS554 - crLHS1067*crLHS557 - crLHS1069*crLHS557 + crLHS748); + rLHS(17,5)+=gauss_weight*(DN_v(5,0)*crLHS72 + DN_v(5,1)*crLHS373 + DN_v(5,2)*crLHS558 - crLHS1067*crLHS562 - crLHS1069*crLHS562 + crLHS1071 + crLHS777); + rLHS(17,6)+=gauss_weight*(DN_v(5,0)*crLHS79 + DN_v(5,1)*crLHS377 + DN_v(5,2)*crLHS563 - crLHS1067*crLHS567 - crLHS1069*crLHS567 + crLHS817); + rLHS(17,7)+=gauss_weight*(DN_v(5,0)*crLHS96 + DN_v(5,1)*crLHS384 + DN_v(5,2)*crLHS568 - crLHS1067*crLHS571 - crLHS1069*crLHS571 + crLHS852); + rLHS(17,8)+=gauss_weight*(DN_v(5,0)*crLHS104 + DN_v(5,1)*crLHS392 + DN_v(5,2)*crLHS572 - crLHS1067*crLHS576 - crLHS1069*crLHS576 + crLHS1072 + crLHS878); + rLHS(17,9)+=gauss_weight*(DN_v(5,0)*crLHS111 + DN_v(5,1)*crLHS396 + DN_v(5,2)*crLHS577 - crLHS1067*crLHS581 - crLHS1069*crLHS581 + crLHS914); + rLHS(17,10)+=gauss_weight*(DN_v(5,0)*crLHS128 + DN_v(5,1)*crLHS403 + DN_v(5,2)*crLHS582 - crLHS1067*crLHS585 - crLHS1069*crLHS585 + crLHS946); + rLHS(17,11)+=gauss_weight*(DN_v(5,0)*crLHS136 + DN_v(5,1)*crLHS411 + DN_v(5,2)*crLHS586 - crLHS1067*crLHS590 - crLHS1069*crLHS590 + crLHS1073 + crLHS969); + rLHS(17,12)+=gauss_weight*(DN_v(5,0)*crLHS143 + DN_v(5,1)*crLHS415 + DN_v(5,2)*crLHS591 + crLHS1001 - crLHS1067*crLHS595 - crLHS1069*crLHS595); + rLHS(17,13)+=gauss_weight*(DN_v(5,0)*crLHS160 + DN_v(5,1)*crLHS422 + DN_v(5,2)*crLHS596 + crLHS1030 - crLHS1067*crLHS599 - crLHS1069*crLHS599); + rLHS(17,14)+=gauss_weight*(DN_v(5,0)*crLHS168 + DN_v(5,1)*crLHS430 + DN_v(5,2)*crLHS600 + crLHS1050 - crLHS1067*crLHS604 - crLHS1069*crLHS604 + crLHS1074); + rLHS(17,15)+=gauss_weight*(DN_v(5,0)*crLHS175 + DN_v(5,1)*crLHS434 + DN_v(5,2)*crLHS605 - crLHS1067*crLHS609 - crLHS1069*crLHS609 + crLHS1078); + rLHS(17,16)+=gauss_weight*(DN_v(5,0)*crLHS192 + DN_v(5,1)*crLHS441 + DN_v(5,2)*crLHS610 - crLHS1067*crLHS613 - crLHS1069*crLHS613 + crLHS1104); + rLHS(17,17)+=gauss_weight*(DN_v(5,0)*crLHS200 + DN_v(5,1)*crLHS449 + std::pow(DN_v(5,2), 2)*crLHS9 + DN_v(5,2)*crLHS614 - crLHS1067*crLHS618 - crLHS1069*crLHS618 + crLHS1075); + rLHS(17,18)+=gauss_weight*(DN_v(5,0)*crLHS207 + DN_v(5,1)*crLHS453 + DN_v(5,2)*crLHS619 - crLHS1067*crLHS623 - crLHS1069*crLHS623 + crLHS1122); + rLHS(17,19)+=gauss_weight*(DN_v(5,0)*crLHS224 + DN_v(5,1)*crLHS460 + DN_v(5,2)*crLHS624 - crLHS1067*crLHS627 - crLHS1069*crLHS627 + crLHS1123); + rLHS(17,20)+=gauss_weight*(DN_v(5,0)*crLHS232 + DN_v(5,1)*crLHS468 + DN_v(5,2)*crLHS628 - crLHS1067*crLHS632 - crLHS1069*crLHS632 + crLHS1081 + crLHS1124); + rLHS(17,21)+=gauss_weight*(DN_v(5,0)*crLHS239 + DN_v(5,1)*crLHS472 + DN_v(5,2)*crLHS633 - crLHS1067*crLHS637 - crLHS1069*crLHS637 + crLHS1125); + rLHS(17,22)+=gauss_weight*(DN_v(5,0)*crLHS256 + DN_v(5,1)*crLHS479 + DN_v(5,2)*crLHS638 - crLHS1067*crLHS641 - crLHS1069*crLHS641 + crLHS1126); + rLHS(17,23)+=gauss_weight*(DN_v(5,0)*crLHS264 + DN_v(5,1)*crLHS487 + DN_v(5,2)*crLHS642 - crLHS1067*crLHS646 - crLHS1069*crLHS646 + crLHS1086 + crLHS1127); + rLHS(17,24)+=gauss_weight*(DN_v(5,0)*crLHS271 + DN_v(5,1)*crLHS491 + DN_v(5,2)*crLHS647 - crLHS1067*crLHS651 - crLHS1069*crLHS651 + crLHS1128); + rLHS(17,25)+=gauss_weight*(DN_v(5,0)*crLHS288 + DN_v(5,1)*crLHS498 + DN_v(5,2)*crLHS652 - crLHS1067*crLHS655 - crLHS1069*crLHS655 + crLHS1129); + rLHS(17,26)+=gauss_weight*(DN_v(5,0)*crLHS296 + DN_v(5,1)*crLHS506 + DN_v(5,2)*crLHS656 - crLHS1067*crLHS660 - crLHS1069*crLHS660 + crLHS1091 + crLHS1130); + rLHS(17,27)+=gauss_weight*(DN_v(5,0)*crLHS303 + DN_v(5,1)*crLHS510 + DN_v(5,2)*crLHS661 - crLHS1067*crLHS665 - crLHS1069*crLHS665 + crLHS1131); + rLHS(17,28)+=gauss_weight*(DN_v(5,0)*crLHS319 + DN_v(5,1)*crLHS517 + DN_v(5,2)*crLHS666 - crLHS1067*crLHS669 - crLHS1069*crLHS669 + crLHS1132); + rLHS(17,29)+=gauss_weight*(DN_v(5,0)*crLHS327 + DN_v(5,1)*crLHS525 + DN_v(5,2)*crLHS670 - crLHS1067*crLHS674 - crLHS1069*crLHS674 + crLHS1096 + crLHS1133); + rLHS(17,30)+=gauss_weight*(crLHS1068*crLHS676 + crLHS1134 + crLHS181*crLHS676); + rLHS(17,31)+=gauss_weight*(crLHS1068*crLHS678 + crLHS1135 + crLHS181*crLHS678); + rLHS(17,32)+=gauss_weight*(crLHS1068*crLHS680 + crLHS1136 + crLHS181*crLHS680); + rLHS(17,33)+=gauss_weight*(crLHS1068*crLHS682 + crLHS1137 + crLHS181*crLHS682); + rLHS(18,0)+=gauss_weight*(DN_v(6,0)*crLHS0 + DN_v(6,1)*crLHS2 + DN_v(6,2)*crLHS4 - crLHS1138*crLHS19 - crLHS1140*crLHS19 + crLHS1141 + crLHS208); + rLHS(18,1)+=gauss_weight*(DN_v(6,0)*crLHS26 + DN_v(6,1)*crLHS28 + DN_v(6,2)*crLHS31 - crLHS1138*crLHS35 - crLHS1140*crLHS35 + crLHS454); + rLHS(18,2)+=gauss_weight*(DN_v(6,0)*crLHS36 + DN_v(6,1)*crLHS38 + DN_v(6,2)*crLHS40 - crLHS1138*crLHS42 - crLHS1140*crLHS42 + crLHS620); + rLHS(18,3)+=gauss_weight*(DN_v(6,0)*crLHS43 + DN_v(6,1)*crLHS45 + DN_v(6,2)*crLHS47 - crLHS1138*crLHS56 - crLHS1140*crLHS56 + crLHS1142 + crLHS711); + rLHS(18,4)+=gauss_weight*(DN_v(6,0)*crLHS59 + DN_v(6,1)*crLHS61 + DN_v(6,2)*crLHS64 - crLHS1138*crLHS67 - crLHS1140*crLHS67 + crLHS749); + rLHS(18,5)+=gauss_weight*(DN_v(6,0)*crLHS68 + DN_v(6,1)*crLHS70 + DN_v(6,2)*crLHS72 - crLHS1138*crLHS74 - crLHS1140*crLHS74 + crLHS778); + rLHS(18,6)+=gauss_weight*(DN_v(6,0)*crLHS75 + DN_v(6,1)*crLHS77 + DN_v(6,2)*crLHS79 - crLHS1138*crLHS88 - crLHS1140*crLHS88 + crLHS1143 + crLHS818); + rLHS(18,7)+=gauss_weight*(DN_v(6,0)*crLHS91 + DN_v(6,1)*crLHS93 + DN_v(6,2)*crLHS96 - crLHS1138*crLHS99 - crLHS1140*crLHS99 + crLHS853); + rLHS(18,8)+=gauss_weight*(DN_v(6,0)*crLHS100 + DN_v(6,1)*crLHS102 + DN_v(6,2)*crLHS104 - crLHS106*crLHS1138 - crLHS106*crLHS1140 + crLHS879); + rLHS(18,9)+=gauss_weight*(DN_v(6,0)*crLHS107 + DN_v(6,1)*crLHS109 + DN_v(6,2)*crLHS111 - crLHS1138*crLHS120 - crLHS1140*crLHS120 + crLHS1144 + crLHS915); + rLHS(18,10)+=gauss_weight*(DN_v(6,0)*crLHS123 + DN_v(6,1)*crLHS125 + DN_v(6,2)*crLHS128 - crLHS1138*crLHS131 - crLHS1140*crLHS131 + crLHS947); + rLHS(18,11)+=gauss_weight*(DN_v(6,0)*crLHS132 + DN_v(6,1)*crLHS134 + DN_v(6,2)*crLHS136 - crLHS1138*crLHS138 - crLHS1140*crLHS138 + crLHS970); + rLHS(18,12)+=gauss_weight*(DN_v(6,0)*crLHS139 + DN_v(6,1)*crLHS141 + DN_v(6,2)*crLHS143 + crLHS1002 - crLHS1138*crLHS152 - crLHS1140*crLHS152 + crLHS1145); + rLHS(18,13)+=gauss_weight*(DN_v(6,0)*crLHS155 + DN_v(6,1)*crLHS157 + DN_v(6,2)*crLHS160 + crLHS1031 - crLHS1138*crLHS163 - crLHS1140*crLHS163); + rLHS(18,14)+=gauss_weight*(DN_v(6,0)*crLHS164 + DN_v(6,1)*crLHS166 + DN_v(6,2)*crLHS168 + crLHS1051 - crLHS1138*crLHS170 - crLHS1140*crLHS170); + rLHS(18,15)+=gauss_weight*(DN_v(6,0)*crLHS171 + DN_v(6,1)*crLHS173 + DN_v(6,2)*crLHS175 + crLHS1079 - crLHS1138*crLHS184 - crLHS1140*crLHS184 + crLHS1146); + rLHS(18,16)+=gauss_weight*(DN_v(6,0)*crLHS187 + DN_v(6,1)*crLHS189 + DN_v(6,2)*crLHS192 + crLHS1105 - crLHS1138*crLHS195 - crLHS1140*crLHS195); + rLHS(18,17)+=gauss_weight*(DN_v(6,0)*crLHS196 + DN_v(6,1)*crLHS198 + DN_v(6,2)*crLHS200 + crLHS1122 - crLHS1138*crLHS202 - crLHS1140*crLHS202); + rLHS(18,18)+=gauss_weight*(std::pow(DN_v(6,0), 2)*crLHS9 + DN_v(6,0)*crLHS203 + DN_v(6,1)*crLHS205 + DN_v(6,2)*crLHS207 - crLHS1138*crLHS216 - crLHS1140*crLHS216 + crLHS1147); + rLHS(18,19)+=gauss_weight*(DN_v(6,0)*crLHS219 + DN_v(6,1)*crLHS221 + DN_v(6,2)*crLHS224 - crLHS1138*crLHS227 - crLHS1140*crLHS227 + crLHS1149); + rLHS(18,20)+=gauss_weight*(DN_v(6,0)*crLHS228 + DN_v(6,1)*crLHS230 + DN_v(6,2)*crLHS232 - crLHS1138*crLHS234 - crLHS1140*crLHS234 + crLHS1150); + rLHS(18,21)+=gauss_weight*(DN_v(6,0)*crLHS235 + DN_v(6,1)*crLHS237 + DN_v(6,2)*crLHS239 - crLHS1138*crLHS248 - crLHS1140*crLHS248 + crLHS1151 + crLHS1153); + rLHS(18,22)+=gauss_weight*(DN_v(6,0)*crLHS251 + DN_v(6,1)*crLHS253 + DN_v(6,2)*crLHS256 - crLHS1138*crLHS259 - crLHS1140*crLHS259 + crLHS1154); + rLHS(18,23)+=gauss_weight*(DN_v(6,0)*crLHS260 + DN_v(6,1)*crLHS262 + DN_v(6,2)*crLHS264 - crLHS1138*crLHS266 - crLHS1140*crLHS266 + crLHS1155); + rLHS(18,24)+=gauss_weight*(DN_v(6,0)*crLHS267 + DN_v(6,1)*crLHS269 + DN_v(6,2)*crLHS271 - crLHS1138*crLHS280 - crLHS1140*crLHS280 + crLHS1156 + crLHS1158); + rLHS(18,25)+=gauss_weight*(DN_v(6,0)*crLHS283 + DN_v(6,1)*crLHS285 + DN_v(6,2)*crLHS288 - crLHS1138*crLHS291 - crLHS1140*crLHS291 + crLHS1159); + rLHS(18,26)+=gauss_weight*(DN_v(6,0)*crLHS292 + DN_v(6,1)*crLHS294 + DN_v(6,2)*crLHS296 - crLHS1138*crLHS298 - crLHS1140*crLHS298 + crLHS1160); + rLHS(18,27)+=gauss_weight*(DN_v(6,0)*crLHS299 + DN_v(6,1)*crLHS301 + DN_v(6,2)*crLHS303 - crLHS1138*crLHS311 - crLHS1140*crLHS311 + crLHS1161 + crLHS1163); + rLHS(18,28)+=gauss_weight*(DN_v(6,0)*crLHS314 + DN_v(6,1)*crLHS316 + DN_v(6,2)*crLHS319 - crLHS1138*crLHS322 - crLHS1140*crLHS322 + crLHS1164); + rLHS(18,29)+=gauss_weight*(DN_v(6,0)*crLHS323 + DN_v(6,1)*crLHS325 + DN_v(6,2)*crLHS327 - crLHS1138*crLHS329 - crLHS1140*crLHS329 + crLHS1165); + rLHS(18,30)+=gauss_weight*(crLHS1139*crLHS331 + crLHS1166 + crLHS213*crLHS331); + rLHS(18,31)+=gauss_weight*(crLHS1139*crLHS333 + crLHS1167 + crLHS213*crLHS333); + rLHS(18,32)+=gauss_weight*(crLHS1139*crLHS335 + crLHS1168 + crLHS213*crLHS335); + rLHS(18,33)+=gauss_weight*(crLHS1139*crLHS337 + crLHS1169 + crLHS213*crLHS337); + rLHS(19,0)+=gauss_weight*(DN_v(6,0)*crLHS2 + DN_v(6,1)*crLHS338 + DN_v(6,2)*crLHS339 - crLHS1138*crLHS342 - crLHS1140*crLHS342 + crLHS225); + rLHS(19,1)+=gauss_weight*(DN_v(6,0)*crLHS28 + DN_v(6,1)*crLHS343 + DN_v(6,2)*crLHS345 - crLHS1138*crLHS350 - crLHS1140*crLHS350 + crLHS1141 + crLHS461); + rLHS(19,2)+=gauss_weight*(DN_v(6,0)*crLHS38 + DN_v(6,1)*crLHS351 + DN_v(6,2)*crLHS353 - crLHS1138*crLHS356 - crLHS1140*crLHS356 + crLHS625); + rLHS(19,3)+=gauss_weight*(DN_v(6,0)*crLHS45 + DN_v(6,1)*crLHS357 + DN_v(6,2)*crLHS358 - crLHS1138*crLHS362 - crLHS1140*crLHS362 + crLHS714); + rLHS(19,4)+=gauss_weight*(DN_v(6,0)*crLHS61 + DN_v(6,1)*crLHS363 + DN_v(6,2)*crLHS365 - crLHS1138*crLHS370 - crLHS1140*crLHS370 + crLHS1142 + crLHS750); + rLHS(19,5)+=gauss_weight*(DN_v(6,0)*crLHS70 + DN_v(6,1)*crLHS371 + DN_v(6,2)*crLHS373 - crLHS1138*crLHS375 - crLHS1140*crLHS375 + crLHS779); + rLHS(19,6)+=gauss_weight*(DN_v(6,0)*crLHS77 + DN_v(6,1)*crLHS376 + DN_v(6,2)*crLHS377 - crLHS1138*crLHS381 - crLHS1140*crLHS381 + crLHS821); + rLHS(19,7)+=gauss_weight*(DN_v(6,0)*crLHS93 + DN_v(6,1)*crLHS382 + DN_v(6,2)*crLHS384 - crLHS1138*crLHS389 - crLHS1140*crLHS389 + crLHS1143 + crLHS854); + rLHS(19,8)+=gauss_weight*(DN_v(6,0)*crLHS102 + DN_v(6,1)*crLHS390 + DN_v(6,2)*crLHS392 - crLHS1138*crLHS394 - crLHS1140*crLHS394 + crLHS880); + rLHS(19,9)+=gauss_weight*(DN_v(6,0)*crLHS109 + DN_v(6,1)*crLHS395 + DN_v(6,2)*crLHS396 - crLHS1138*crLHS400 - crLHS1140*crLHS400 + crLHS918); + rLHS(19,10)+=gauss_weight*(DN_v(6,0)*crLHS125 + DN_v(6,1)*crLHS401 + DN_v(6,2)*crLHS403 - crLHS1138*crLHS408 - crLHS1140*crLHS408 + crLHS1144 + crLHS948); + rLHS(19,11)+=gauss_weight*(DN_v(6,0)*crLHS134 + DN_v(6,1)*crLHS409 + DN_v(6,2)*crLHS411 - crLHS1138*crLHS413 - crLHS1140*crLHS413 + crLHS971); + rLHS(19,12)+=gauss_weight*(DN_v(6,0)*crLHS141 + DN_v(6,1)*crLHS414 + DN_v(6,2)*crLHS415 + crLHS1005 - crLHS1138*crLHS419 - crLHS1140*crLHS419); + rLHS(19,13)+=gauss_weight*(DN_v(6,0)*crLHS157 + DN_v(6,1)*crLHS420 + DN_v(6,2)*crLHS422 + crLHS1032 - crLHS1138*crLHS427 - crLHS1140*crLHS427 + crLHS1145); + rLHS(19,14)+=gauss_weight*(DN_v(6,0)*crLHS166 + DN_v(6,1)*crLHS428 + DN_v(6,2)*crLHS430 + crLHS1052 - crLHS1138*crLHS432 - crLHS1140*crLHS432); + rLHS(19,15)+=gauss_weight*(DN_v(6,0)*crLHS173 + DN_v(6,1)*crLHS433 + DN_v(6,2)*crLHS434 + crLHS1082 - crLHS1138*crLHS438 - crLHS1140*crLHS438); + rLHS(19,16)+=gauss_weight*(DN_v(6,0)*crLHS189 + DN_v(6,1)*crLHS439 + DN_v(6,2)*crLHS441 + crLHS1106 - crLHS1138*crLHS446 - crLHS1140*crLHS446 + crLHS1146); + rLHS(19,17)+=gauss_weight*(DN_v(6,0)*crLHS198 + DN_v(6,1)*crLHS447 + DN_v(6,2)*crLHS449 + crLHS1123 - crLHS1138*crLHS451 - crLHS1140*crLHS451); + rLHS(19,18)+=gauss_weight*(DN_v(6,0)*crLHS205 + DN_v(6,1)*crLHS452 + DN_v(6,2)*crLHS453 - crLHS1138*crLHS457 - crLHS1140*crLHS457 + crLHS1149); + rLHS(19,19)+=gauss_weight*(DN_v(6,0)*crLHS221 + std::pow(DN_v(6,1), 2)*crLHS9 + DN_v(6,1)*crLHS458 + DN_v(6,2)*crLHS460 - crLHS1138*crLHS465 - crLHS1140*crLHS465 + crLHS1147); + rLHS(19,20)+=gauss_weight*(DN_v(6,0)*crLHS230 + DN_v(6,1)*crLHS466 + DN_v(6,2)*crLHS468 - crLHS1138*crLHS470 - crLHS1140*crLHS470 + crLHS1171); + rLHS(19,21)+=gauss_weight*(DN_v(6,0)*crLHS237 + DN_v(6,1)*crLHS471 + DN_v(6,2)*crLHS472 - crLHS1138*crLHS476 - crLHS1140*crLHS476 + crLHS1172); + rLHS(19,22)+=gauss_weight*(DN_v(6,0)*crLHS253 + DN_v(6,1)*crLHS477 + DN_v(6,2)*crLHS479 - crLHS1138*crLHS484 - crLHS1140*crLHS484 + crLHS1153 + crLHS1173); + rLHS(19,23)+=gauss_weight*(DN_v(6,0)*crLHS262 + DN_v(6,1)*crLHS485 + DN_v(6,2)*crLHS487 - crLHS1138*crLHS489 - crLHS1140*crLHS489 + crLHS1174); + rLHS(19,24)+=gauss_weight*(DN_v(6,0)*crLHS269 + DN_v(6,1)*crLHS490 + DN_v(6,2)*crLHS491 - crLHS1138*crLHS495 - crLHS1140*crLHS495 + crLHS1175); + rLHS(19,25)+=gauss_weight*(DN_v(6,0)*crLHS285 + DN_v(6,1)*crLHS496 + DN_v(6,2)*crLHS498 - crLHS1138*crLHS503 - crLHS1140*crLHS503 + crLHS1158 + crLHS1176); + rLHS(19,26)+=gauss_weight*(DN_v(6,0)*crLHS294 + DN_v(6,1)*crLHS504 + DN_v(6,2)*crLHS506 - crLHS1138*crLHS508 - crLHS1140*crLHS508 + crLHS1177); + rLHS(19,27)+=gauss_weight*(DN_v(6,0)*crLHS301 + DN_v(6,1)*crLHS509 + DN_v(6,2)*crLHS510 - crLHS1138*crLHS514 - crLHS1140*crLHS514 + crLHS1178); + rLHS(19,28)+=gauss_weight*(DN_v(6,0)*crLHS316 + DN_v(6,1)*crLHS515 + DN_v(6,2)*crLHS517 - crLHS1138*crLHS522 - crLHS1140*crLHS522 + crLHS1163 + crLHS1179); + rLHS(19,29)+=gauss_weight*(DN_v(6,0)*crLHS325 + DN_v(6,1)*crLHS523 + DN_v(6,2)*crLHS525 - crLHS1138*crLHS527 - crLHS1140*crLHS527 + crLHS1180); + rLHS(19,30)+=gauss_weight*(crLHS1139*crLHS529 + crLHS1181 + crLHS213*crLHS529); + rLHS(19,31)+=gauss_weight*(crLHS1139*crLHS531 + crLHS1182 + crLHS213*crLHS531); + rLHS(19,32)+=gauss_weight*(crLHS1139*crLHS533 + crLHS1183 + crLHS213*crLHS533); + rLHS(19,33)+=gauss_weight*(crLHS1139*crLHS535 + crLHS1184 + crLHS213*crLHS535); + rLHS(20,0)+=gauss_weight*(DN_v(6,0)*crLHS4 + DN_v(6,1)*crLHS339 + DN_v(6,2)*crLHS536 - crLHS1138*crLHS539 - crLHS1140*crLHS539 + crLHS233); + rLHS(20,1)+=gauss_weight*(DN_v(6,0)*crLHS31 + DN_v(6,1)*crLHS345 + DN_v(6,2)*crLHS540 - crLHS1138*crLHS542 - crLHS1140*crLHS542 + crLHS469); + rLHS(20,2)+=gauss_weight*(DN_v(6,0)*crLHS40 + DN_v(6,1)*crLHS353 + DN_v(6,2)*crLHS543 - crLHS1138*crLHS547 - crLHS1140*crLHS547 + crLHS1141 + crLHS629); + rLHS(20,3)+=gauss_weight*(DN_v(6,0)*crLHS47 + DN_v(6,1)*crLHS358 + DN_v(6,2)*crLHS548 - crLHS1138*crLHS553 - crLHS1140*crLHS553 + crLHS715); + rLHS(20,4)+=gauss_weight*(DN_v(6,0)*crLHS64 + DN_v(6,1)*crLHS365 + DN_v(6,2)*crLHS554 - crLHS1138*crLHS557 - crLHS1140*crLHS557 + crLHS751); + rLHS(20,5)+=gauss_weight*(DN_v(6,0)*crLHS72 + DN_v(6,1)*crLHS373 + DN_v(6,2)*crLHS558 - crLHS1138*crLHS562 - crLHS1140*crLHS562 + crLHS1142 + crLHS780); + rLHS(20,6)+=gauss_weight*(DN_v(6,0)*crLHS79 + DN_v(6,1)*crLHS377 + DN_v(6,2)*crLHS563 - crLHS1138*crLHS567 - crLHS1140*crLHS567 + crLHS822); + rLHS(20,7)+=gauss_weight*(DN_v(6,0)*crLHS96 + DN_v(6,1)*crLHS384 + DN_v(6,2)*crLHS568 - crLHS1138*crLHS571 - crLHS1140*crLHS571 + crLHS855); + rLHS(20,8)+=gauss_weight*(DN_v(6,0)*crLHS104 + DN_v(6,1)*crLHS392 + DN_v(6,2)*crLHS572 - crLHS1138*crLHS576 - crLHS1140*crLHS576 + crLHS1143 + crLHS881); + rLHS(20,9)+=gauss_weight*(DN_v(6,0)*crLHS111 + DN_v(6,1)*crLHS396 + DN_v(6,2)*crLHS577 - crLHS1138*crLHS581 - crLHS1140*crLHS581 + crLHS919); + rLHS(20,10)+=gauss_weight*(DN_v(6,0)*crLHS128 + DN_v(6,1)*crLHS403 + DN_v(6,2)*crLHS582 - crLHS1138*crLHS585 - crLHS1140*crLHS585 + crLHS949); + rLHS(20,11)+=gauss_weight*(DN_v(6,0)*crLHS136 + DN_v(6,1)*crLHS411 + DN_v(6,2)*crLHS586 - crLHS1138*crLHS590 - crLHS1140*crLHS590 + crLHS1144 + crLHS972); + rLHS(20,12)+=gauss_weight*(DN_v(6,0)*crLHS143 + DN_v(6,1)*crLHS415 + DN_v(6,2)*crLHS591 + crLHS1006 - crLHS1138*crLHS595 - crLHS1140*crLHS595); + rLHS(20,13)+=gauss_weight*(DN_v(6,0)*crLHS160 + DN_v(6,1)*crLHS422 + DN_v(6,2)*crLHS596 + crLHS1033 - crLHS1138*crLHS599 - crLHS1140*crLHS599); + rLHS(20,14)+=gauss_weight*(DN_v(6,0)*crLHS168 + DN_v(6,1)*crLHS430 + DN_v(6,2)*crLHS600 + crLHS1053 - crLHS1138*crLHS604 - crLHS1140*crLHS604 + crLHS1145); + rLHS(20,15)+=gauss_weight*(DN_v(6,0)*crLHS175 + DN_v(6,1)*crLHS434 + DN_v(6,2)*crLHS605 + crLHS1083 - crLHS1138*crLHS609 - crLHS1140*crLHS609); + rLHS(20,16)+=gauss_weight*(DN_v(6,0)*crLHS192 + DN_v(6,1)*crLHS441 + DN_v(6,2)*crLHS610 + crLHS1107 - crLHS1138*crLHS613 - crLHS1140*crLHS613); + rLHS(20,17)+=gauss_weight*(DN_v(6,0)*crLHS200 + DN_v(6,1)*crLHS449 + DN_v(6,2)*crLHS614 + crLHS1124 - crLHS1138*crLHS618 - crLHS1140*crLHS618 + crLHS1146); + rLHS(20,18)+=gauss_weight*(DN_v(6,0)*crLHS207 + DN_v(6,1)*crLHS453 + DN_v(6,2)*crLHS619 - crLHS1138*crLHS623 - crLHS1140*crLHS623 + crLHS1150); + rLHS(20,19)+=gauss_weight*(DN_v(6,0)*crLHS224 + DN_v(6,1)*crLHS460 + DN_v(6,2)*crLHS624 - crLHS1138*crLHS627 - crLHS1140*crLHS627 + crLHS1171); + rLHS(20,20)+=gauss_weight*(DN_v(6,0)*crLHS232 + DN_v(6,1)*crLHS468 + std::pow(DN_v(6,2), 2)*crLHS9 + DN_v(6,2)*crLHS628 - crLHS1138*crLHS632 - crLHS1140*crLHS632 + crLHS1147); + rLHS(20,21)+=gauss_weight*(DN_v(6,0)*crLHS239 + DN_v(6,1)*crLHS472 + DN_v(6,2)*crLHS633 - crLHS1138*crLHS637 - crLHS1140*crLHS637 + crLHS1186); + rLHS(20,22)+=gauss_weight*(DN_v(6,0)*crLHS256 + DN_v(6,1)*crLHS479 + DN_v(6,2)*crLHS638 - crLHS1138*crLHS641 - crLHS1140*crLHS641 + crLHS1187); + rLHS(20,23)+=gauss_weight*(DN_v(6,0)*crLHS264 + DN_v(6,1)*crLHS487 + DN_v(6,2)*crLHS642 - crLHS1138*crLHS646 - crLHS1140*crLHS646 + crLHS1153 + crLHS1188); + rLHS(20,24)+=gauss_weight*(DN_v(6,0)*crLHS271 + DN_v(6,1)*crLHS491 + DN_v(6,2)*crLHS647 - crLHS1138*crLHS651 - crLHS1140*crLHS651 + crLHS1189); + rLHS(20,25)+=gauss_weight*(DN_v(6,0)*crLHS288 + DN_v(6,1)*crLHS498 + DN_v(6,2)*crLHS652 - crLHS1138*crLHS655 - crLHS1140*crLHS655 + crLHS1190); + rLHS(20,26)+=gauss_weight*(DN_v(6,0)*crLHS296 + DN_v(6,1)*crLHS506 + DN_v(6,2)*crLHS656 - crLHS1138*crLHS660 - crLHS1140*crLHS660 + crLHS1158 + crLHS1191); + rLHS(20,27)+=gauss_weight*(DN_v(6,0)*crLHS303 + DN_v(6,1)*crLHS510 + DN_v(6,2)*crLHS661 - crLHS1138*crLHS665 - crLHS1140*crLHS665 + crLHS1192); + rLHS(20,28)+=gauss_weight*(DN_v(6,0)*crLHS319 + DN_v(6,1)*crLHS517 + DN_v(6,2)*crLHS666 - crLHS1138*crLHS669 - crLHS1140*crLHS669 + crLHS1193); + rLHS(20,29)+=gauss_weight*(DN_v(6,0)*crLHS327 + DN_v(6,1)*crLHS525 + DN_v(6,2)*crLHS670 - crLHS1138*crLHS674 - crLHS1140*crLHS674 + crLHS1163 + crLHS1194); + rLHS(20,30)+=gauss_weight*(crLHS1139*crLHS676 + crLHS1195 + crLHS213*crLHS676); + rLHS(20,31)+=gauss_weight*(crLHS1139*crLHS678 + crLHS1196 + crLHS213*crLHS678); + rLHS(20,32)+=gauss_weight*(crLHS1139*crLHS680 + crLHS1197 + crLHS213*crLHS680); + rLHS(20,33)+=gauss_weight*(crLHS1139*crLHS682 + crLHS1198 + crLHS213*crLHS682); + rLHS(21,0)+=gauss_weight*(DN_v(7,0)*crLHS0 + DN_v(7,1)*crLHS2 + DN_v(7,2)*crLHS4 - crLHS1199*crLHS19 - crLHS1201*crLHS19 + crLHS1202 + crLHS240); + rLHS(21,1)+=gauss_weight*(DN_v(7,0)*crLHS26 + DN_v(7,1)*crLHS28 + DN_v(7,2)*crLHS31 - crLHS1199*crLHS35 - crLHS1201*crLHS35 + crLHS473); + rLHS(21,2)+=gauss_weight*(DN_v(7,0)*crLHS36 + DN_v(7,1)*crLHS38 + DN_v(7,2)*crLHS40 - crLHS1199*crLHS42 - crLHS1201*crLHS42 + crLHS634); + rLHS(21,3)+=gauss_weight*(DN_v(7,0)*crLHS43 + DN_v(7,1)*crLHS45 + DN_v(7,2)*crLHS47 - crLHS1199*crLHS56 - crLHS1201*crLHS56 + crLHS1203 + crLHS716); + rLHS(21,4)+=gauss_weight*(DN_v(7,0)*crLHS59 + DN_v(7,1)*crLHS61 + DN_v(7,2)*crLHS64 - crLHS1199*crLHS67 - crLHS1201*crLHS67 + crLHS752); + rLHS(21,5)+=gauss_weight*(DN_v(7,0)*crLHS68 + DN_v(7,1)*crLHS70 + DN_v(7,2)*crLHS72 - crLHS1199*crLHS74 - crLHS1201*crLHS74 + crLHS781); + rLHS(21,6)+=gauss_weight*(DN_v(7,0)*crLHS75 + DN_v(7,1)*crLHS77 + DN_v(7,2)*crLHS79 - crLHS1199*crLHS88 - crLHS1201*crLHS88 + crLHS1204 + crLHS823); + rLHS(21,7)+=gauss_weight*(DN_v(7,0)*crLHS91 + DN_v(7,1)*crLHS93 + DN_v(7,2)*crLHS96 - crLHS1199*crLHS99 - crLHS1201*crLHS99 + crLHS856); + rLHS(21,8)+=gauss_weight*(DN_v(7,0)*crLHS100 + DN_v(7,1)*crLHS102 + DN_v(7,2)*crLHS104 - crLHS106*crLHS1199 - crLHS106*crLHS1201 + crLHS882); + rLHS(21,9)+=gauss_weight*(DN_v(7,0)*crLHS107 + DN_v(7,1)*crLHS109 + DN_v(7,2)*crLHS111 - crLHS1199*crLHS120 - crLHS120*crLHS1201 + crLHS1205 + crLHS920); + rLHS(21,10)+=gauss_weight*(DN_v(7,0)*crLHS123 + DN_v(7,1)*crLHS125 + DN_v(7,2)*crLHS128 - crLHS1199*crLHS131 - crLHS1201*crLHS131 + crLHS950); + rLHS(21,11)+=gauss_weight*(DN_v(7,0)*crLHS132 + DN_v(7,1)*crLHS134 + DN_v(7,2)*crLHS136 - crLHS1199*crLHS138 - crLHS1201*crLHS138 + crLHS973); + rLHS(21,12)+=gauss_weight*(DN_v(7,0)*crLHS139 + DN_v(7,1)*crLHS141 + DN_v(7,2)*crLHS143 + crLHS1007 - crLHS1199*crLHS152 - crLHS1201*crLHS152 + crLHS1206); + rLHS(21,13)+=gauss_weight*(DN_v(7,0)*crLHS155 + DN_v(7,1)*crLHS157 + DN_v(7,2)*crLHS160 + crLHS1034 - crLHS1199*crLHS163 - crLHS1201*crLHS163); + rLHS(21,14)+=gauss_weight*(DN_v(7,0)*crLHS164 + DN_v(7,1)*crLHS166 + DN_v(7,2)*crLHS168 + crLHS1054 - crLHS1199*crLHS170 - crLHS1201*crLHS170); + rLHS(21,15)+=gauss_weight*(DN_v(7,0)*crLHS171 + DN_v(7,1)*crLHS173 + DN_v(7,2)*crLHS175 + crLHS1084 - crLHS1199*crLHS184 - crLHS1201*crLHS184 + crLHS1207); + rLHS(21,16)+=gauss_weight*(DN_v(7,0)*crLHS187 + DN_v(7,1)*crLHS189 + DN_v(7,2)*crLHS192 + crLHS1108 - crLHS1199*crLHS195 - crLHS1201*crLHS195); + rLHS(21,17)+=gauss_weight*(DN_v(7,0)*crLHS196 + DN_v(7,1)*crLHS198 + DN_v(7,2)*crLHS200 + crLHS1125 - crLHS1199*crLHS202 - crLHS1201*crLHS202); + rLHS(21,18)+=gauss_weight*(DN_v(7,0)*crLHS203 + DN_v(7,1)*crLHS205 + DN_v(7,2)*crLHS207 + crLHS1151 - crLHS1199*crLHS216 - crLHS1201*crLHS216 + crLHS1208); + rLHS(21,19)+=gauss_weight*(DN_v(7,0)*crLHS219 + DN_v(7,1)*crLHS221 + DN_v(7,2)*crLHS224 + crLHS1172 - crLHS1199*crLHS227 - crLHS1201*crLHS227); + rLHS(21,20)+=gauss_weight*(DN_v(7,0)*crLHS228 + DN_v(7,1)*crLHS230 + DN_v(7,2)*crLHS232 + crLHS1186 - crLHS1199*crLHS234 - crLHS1201*crLHS234); + rLHS(21,21)+=gauss_weight*(std::pow(DN_v(7,0), 2)*crLHS9 + DN_v(7,0)*crLHS235 + DN_v(7,1)*crLHS237 + DN_v(7,2)*crLHS239 - crLHS1199*crLHS248 - crLHS1201*crLHS248 + crLHS1209); + rLHS(21,22)+=gauss_weight*(DN_v(7,0)*crLHS251 + DN_v(7,1)*crLHS253 + DN_v(7,2)*crLHS256 - crLHS1199*crLHS259 - crLHS1201*crLHS259 + crLHS1211); + rLHS(21,23)+=gauss_weight*(DN_v(7,0)*crLHS260 + DN_v(7,1)*crLHS262 + DN_v(7,2)*crLHS264 - crLHS1199*crLHS266 - crLHS1201*crLHS266 + crLHS1212); + rLHS(21,24)+=gauss_weight*(DN_v(7,0)*crLHS267 + DN_v(7,1)*crLHS269 + DN_v(7,2)*crLHS271 - crLHS1199*crLHS280 - crLHS1201*crLHS280 + crLHS1213 + crLHS1215); + rLHS(21,25)+=gauss_weight*(DN_v(7,0)*crLHS283 + DN_v(7,1)*crLHS285 + DN_v(7,2)*crLHS288 - crLHS1199*crLHS291 - crLHS1201*crLHS291 + crLHS1216); + rLHS(21,26)+=gauss_weight*(DN_v(7,0)*crLHS292 + DN_v(7,1)*crLHS294 + DN_v(7,2)*crLHS296 - crLHS1199*crLHS298 - crLHS1201*crLHS298 + crLHS1217); + rLHS(21,27)+=gauss_weight*(DN_v(7,0)*crLHS299 + DN_v(7,1)*crLHS301 + DN_v(7,2)*crLHS303 - crLHS1199*crLHS311 - crLHS1201*crLHS311 + crLHS1218 + crLHS1220); + rLHS(21,28)+=gauss_weight*(DN_v(7,0)*crLHS314 + DN_v(7,1)*crLHS316 + DN_v(7,2)*crLHS319 - crLHS1199*crLHS322 - crLHS1201*crLHS322 + crLHS1221); + rLHS(21,29)+=gauss_weight*(DN_v(7,0)*crLHS323 + DN_v(7,1)*crLHS325 + DN_v(7,2)*crLHS327 - crLHS1199*crLHS329 - crLHS1201*crLHS329 + crLHS1222); + rLHS(21,30)+=gauss_weight*(crLHS1200*crLHS331 + crLHS1223 + crLHS245*crLHS331); + rLHS(21,31)+=gauss_weight*(crLHS1200*crLHS333 + crLHS1224 + crLHS245*crLHS333); + rLHS(21,32)+=gauss_weight*(crLHS1200*crLHS335 + crLHS1225 + crLHS245*crLHS335); + rLHS(21,33)+=gauss_weight*(crLHS1200*crLHS337 + crLHS1226 + crLHS245*crLHS337); + rLHS(22,0)+=gauss_weight*(DN_v(7,0)*crLHS2 + DN_v(7,1)*crLHS338 + DN_v(7,2)*crLHS339 - crLHS1199*crLHS342 - crLHS1201*crLHS342 + crLHS257); + rLHS(22,1)+=gauss_weight*(DN_v(7,0)*crLHS28 + DN_v(7,1)*crLHS343 + DN_v(7,2)*crLHS345 - crLHS1199*crLHS350 - crLHS1201*crLHS350 + crLHS1202 + crLHS480); + rLHS(22,2)+=gauss_weight*(DN_v(7,0)*crLHS38 + DN_v(7,1)*crLHS351 + DN_v(7,2)*crLHS353 - crLHS1199*crLHS356 - crLHS1201*crLHS356 + crLHS639); + rLHS(22,3)+=gauss_weight*(DN_v(7,0)*crLHS45 + DN_v(7,1)*crLHS357 + DN_v(7,2)*crLHS358 - crLHS1199*crLHS362 - crLHS1201*crLHS362 + crLHS719); + rLHS(22,4)+=gauss_weight*(DN_v(7,0)*crLHS61 + DN_v(7,1)*crLHS363 + DN_v(7,2)*crLHS365 - crLHS1199*crLHS370 - crLHS1201*crLHS370 + crLHS1203 + crLHS753); + rLHS(22,5)+=gauss_weight*(DN_v(7,0)*crLHS70 + DN_v(7,1)*crLHS371 + DN_v(7,2)*crLHS373 - crLHS1199*crLHS375 - crLHS1201*crLHS375 + crLHS782); + rLHS(22,6)+=gauss_weight*(DN_v(7,0)*crLHS77 + DN_v(7,1)*crLHS376 + DN_v(7,2)*crLHS377 - crLHS1199*crLHS381 - crLHS1201*crLHS381 + crLHS826); + rLHS(22,7)+=gauss_weight*(DN_v(7,0)*crLHS93 + DN_v(7,1)*crLHS382 + DN_v(7,2)*crLHS384 - crLHS1199*crLHS389 - crLHS1201*crLHS389 + crLHS1204 + crLHS857); + rLHS(22,8)+=gauss_weight*(DN_v(7,0)*crLHS102 + DN_v(7,1)*crLHS390 + DN_v(7,2)*crLHS392 - crLHS1199*crLHS394 - crLHS1201*crLHS394 + crLHS883); + rLHS(22,9)+=gauss_weight*(DN_v(7,0)*crLHS109 + DN_v(7,1)*crLHS395 + DN_v(7,2)*crLHS396 - crLHS1199*crLHS400 - crLHS1201*crLHS400 + crLHS923); + rLHS(22,10)+=gauss_weight*(DN_v(7,0)*crLHS125 + DN_v(7,1)*crLHS401 + DN_v(7,2)*crLHS403 - crLHS1199*crLHS408 - crLHS1201*crLHS408 + crLHS1205 + crLHS951); + rLHS(22,11)+=gauss_weight*(DN_v(7,0)*crLHS134 + DN_v(7,1)*crLHS409 + DN_v(7,2)*crLHS411 - crLHS1199*crLHS413 - crLHS1201*crLHS413 + crLHS974); + rLHS(22,12)+=gauss_weight*(DN_v(7,0)*crLHS141 + DN_v(7,1)*crLHS414 + DN_v(7,2)*crLHS415 + crLHS1010 - crLHS1199*crLHS419 - crLHS1201*crLHS419); + rLHS(22,13)+=gauss_weight*(DN_v(7,0)*crLHS157 + DN_v(7,1)*crLHS420 + DN_v(7,2)*crLHS422 + crLHS1035 - crLHS1199*crLHS427 - crLHS1201*crLHS427 + crLHS1206); + rLHS(22,14)+=gauss_weight*(DN_v(7,0)*crLHS166 + DN_v(7,1)*crLHS428 + DN_v(7,2)*crLHS430 + crLHS1055 - crLHS1199*crLHS432 - crLHS1201*crLHS432); + rLHS(22,15)+=gauss_weight*(DN_v(7,0)*crLHS173 + DN_v(7,1)*crLHS433 + DN_v(7,2)*crLHS434 + crLHS1087 - crLHS1199*crLHS438 - crLHS1201*crLHS438); + rLHS(22,16)+=gauss_weight*(DN_v(7,0)*crLHS189 + DN_v(7,1)*crLHS439 + DN_v(7,2)*crLHS441 + crLHS1109 - crLHS1199*crLHS446 - crLHS1201*crLHS446 + crLHS1207); + rLHS(22,17)+=gauss_weight*(DN_v(7,0)*crLHS198 + DN_v(7,1)*crLHS447 + DN_v(7,2)*crLHS449 + crLHS1126 - crLHS1199*crLHS451 - crLHS1201*crLHS451); + rLHS(22,18)+=gauss_weight*(DN_v(7,0)*crLHS205 + DN_v(7,1)*crLHS452 + DN_v(7,2)*crLHS453 + crLHS1154 - crLHS1199*crLHS457 - crLHS1201*crLHS457); + rLHS(22,19)+=gauss_weight*(DN_v(7,0)*crLHS221 + DN_v(7,1)*crLHS458 + DN_v(7,2)*crLHS460 + crLHS1173 - crLHS1199*crLHS465 - crLHS1201*crLHS465 + crLHS1208); + rLHS(22,20)+=gauss_weight*(DN_v(7,0)*crLHS230 + DN_v(7,1)*crLHS466 + DN_v(7,2)*crLHS468 + crLHS1187 - crLHS1199*crLHS470 - crLHS1201*crLHS470); + rLHS(22,21)+=gauss_weight*(DN_v(7,0)*crLHS237 + DN_v(7,1)*crLHS471 + DN_v(7,2)*crLHS472 - crLHS1199*crLHS476 - crLHS1201*crLHS476 + crLHS1211); + rLHS(22,22)+=gauss_weight*(DN_v(7,0)*crLHS253 + std::pow(DN_v(7,1), 2)*crLHS9 + DN_v(7,1)*crLHS477 + DN_v(7,2)*crLHS479 - crLHS1199*crLHS484 - crLHS1201*crLHS484 + crLHS1209); + rLHS(22,23)+=gauss_weight*(DN_v(7,0)*crLHS262 + DN_v(7,1)*crLHS485 + DN_v(7,2)*crLHS487 - crLHS1199*crLHS489 - crLHS1201*crLHS489 + crLHS1228); + rLHS(22,24)+=gauss_weight*(DN_v(7,0)*crLHS269 + DN_v(7,1)*crLHS490 + DN_v(7,2)*crLHS491 - crLHS1199*crLHS495 - crLHS1201*crLHS495 + crLHS1229); + rLHS(22,25)+=gauss_weight*(DN_v(7,0)*crLHS285 + DN_v(7,1)*crLHS496 + DN_v(7,2)*crLHS498 - crLHS1199*crLHS503 - crLHS1201*crLHS503 + crLHS1215 + crLHS1230); + rLHS(22,26)+=gauss_weight*(DN_v(7,0)*crLHS294 + DN_v(7,1)*crLHS504 + DN_v(7,2)*crLHS506 - crLHS1199*crLHS508 - crLHS1201*crLHS508 + crLHS1231); + rLHS(22,27)+=gauss_weight*(DN_v(7,0)*crLHS301 + DN_v(7,1)*crLHS509 + DN_v(7,2)*crLHS510 - crLHS1199*crLHS514 - crLHS1201*crLHS514 + crLHS1232); + rLHS(22,28)+=gauss_weight*(DN_v(7,0)*crLHS316 + DN_v(7,1)*crLHS515 + DN_v(7,2)*crLHS517 - crLHS1199*crLHS522 - crLHS1201*crLHS522 + crLHS1220 + crLHS1233); + rLHS(22,29)+=gauss_weight*(DN_v(7,0)*crLHS325 + DN_v(7,1)*crLHS523 + DN_v(7,2)*crLHS525 - crLHS1199*crLHS527 - crLHS1201*crLHS527 + crLHS1234); + rLHS(22,30)+=gauss_weight*(crLHS1200*crLHS529 + crLHS1235 + crLHS245*crLHS529); + rLHS(22,31)+=gauss_weight*(crLHS1200*crLHS531 + crLHS1236 + crLHS245*crLHS531); + rLHS(22,32)+=gauss_weight*(crLHS1200*crLHS533 + crLHS1237 + crLHS245*crLHS533); + rLHS(22,33)+=gauss_weight*(crLHS1200*crLHS535 + crLHS1238 + crLHS245*crLHS535); + rLHS(23,0)+=gauss_weight*(DN_v(7,0)*crLHS4 + DN_v(7,1)*crLHS339 + DN_v(7,2)*crLHS536 - crLHS1199*crLHS539 - crLHS1201*crLHS539 + crLHS265); + rLHS(23,1)+=gauss_weight*(DN_v(7,0)*crLHS31 + DN_v(7,1)*crLHS345 + DN_v(7,2)*crLHS540 - crLHS1199*crLHS542 - crLHS1201*crLHS542 + crLHS488); + rLHS(23,2)+=gauss_weight*(DN_v(7,0)*crLHS40 + DN_v(7,1)*crLHS353 + DN_v(7,2)*crLHS543 - crLHS1199*crLHS547 - crLHS1201*crLHS547 + crLHS1202 + crLHS643); + rLHS(23,3)+=gauss_weight*(DN_v(7,0)*crLHS47 + DN_v(7,1)*crLHS358 + DN_v(7,2)*crLHS548 - crLHS1199*crLHS553 - crLHS1201*crLHS553 + crLHS720); + rLHS(23,4)+=gauss_weight*(DN_v(7,0)*crLHS64 + DN_v(7,1)*crLHS365 + DN_v(7,2)*crLHS554 - crLHS1199*crLHS557 - crLHS1201*crLHS557 + crLHS754); + rLHS(23,5)+=gauss_weight*(DN_v(7,0)*crLHS72 + DN_v(7,1)*crLHS373 + DN_v(7,2)*crLHS558 - crLHS1199*crLHS562 - crLHS1201*crLHS562 + crLHS1203 + crLHS783); + rLHS(23,6)+=gauss_weight*(DN_v(7,0)*crLHS79 + DN_v(7,1)*crLHS377 + DN_v(7,2)*crLHS563 - crLHS1199*crLHS567 - crLHS1201*crLHS567 + crLHS827); + rLHS(23,7)+=gauss_weight*(DN_v(7,0)*crLHS96 + DN_v(7,1)*crLHS384 + DN_v(7,2)*crLHS568 - crLHS1199*crLHS571 - crLHS1201*crLHS571 + crLHS858); + rLHS(23,8)+=gauss_weight*(DN_v(7,0)*crLHS104 + DN_v(7,1)*crLHS392 + DN_v(7,2)*crLHS572 - crLHS1199*crLHS576 - crLHS1201*crLHS576 + crLHS1204 + crLHS884); + rLHS(23,9)+=gauss_weight*(DN_v(7,0)*crLHS111 + DN_v(7,1)*crLHS396 + DN_v(7,2)*crLHS577 - crLHS1199*crLHS581 - crLHS1201*crLHS581 + crLHS924); + rLHS(23,10)+=gauss_weight*(DN_v(7,0)*crLHS128 + DN_v(7,1)*crLHS403 + DN_v(7,2)*crLHS582 - crLHS1199*crLHS585 - crLHS1201*crLHS585 + crLHS952); + rLHS(23,11)+=gauss_weight*(DN_v(7,0)*crLHS136 + DN_v(7,1)*crLHS411 + DN_v(7,2)*crLHS586 - crLHS1199*crLHS590 - crLHS1201*crLHS590 + crLHS1205 + crLHS975); + rLHS(23,12)+=gauss_weight*(DN_v(7,0)*crLHS143 + DN_v(7,1)*crLHS415 + DN_v(7,2)*crLHS591 + crLHS1011 - crLHS1199*crLHS595 - crLHS1201*crLHS595); + rLHS(23,13)+=gauss_weight*(DN_v(7,0)*crLHS160 + DN_v(7,1)*crLHS422 + DN_v(7,2)*crLHS596 + crLHS1036 - crLHS1199*crLHS599 - crLHS1201*crLHS599); + rLHS(23,14)+=gauss_weight*(DN_v(7,0)*crLHS168 + DN_v(7,1)*crLHS430 + DN_v(7,2)*crLHS600 + crLHS1056 - crLHS1199*crLHS604 - crLHS1201*crLHS604 + crLHS1206); + rLHS(23,15)+=gauss_weight*(DN_v(7,0)*crLHS175 + DN_v(7,1)*crLHS434 + DN_v(7,2)*crLHS605 + crLHS1088 - crLHS1199*crLHS609 - crLHS1201*crLHS609); + rLHS(23,16)+=gauss_weight*(DN_v(7,0)*crLHS192 + DN_v(7,1)*crLHS441 + DN_v(7,2)*crLHS610 + crLHS1110 - crLHS1199*crLHS613 - crLHS1201*crLHS613); + rLHS(23,17)+=gauss_weight*(DN_v(7,0)*crLHS200 + DN_v(7,1)*crLHS449 + DN_v(7,2)*crLHS614 + crLHS1127 - crLHS1199*crLHS618 - crLHS1201*crLHS618 + crLHS1207); + rLHS(23,18)+=gauss_weight*(DN_v(7,0)*crLHS207 + DN_v(7,1)*crLHS453 + DN_v(7,2)*crLHS619 + crLHS1155 - crLHS1199*crLHS623 - crLHS1201*crLHS623); + rLHS(23,19)+=gauss_weight*(DN_v(7,0)*crLHS224 + DN_v(7,1)*crLHS460 + DN_v(7,2)*crLHS624 + crLHS1174 - crLHS1199*crLHS627 - crLHS1201*crLHS627); + rLHS(23,20)+=gauss_weight*(DN_v(7,0)*crLHS232 + DN_v(7,1)*crLHS468 + DN_v(7,2)*crLHS628 + crLHS1188 - crLHS1199*crLHS632 - crLHS1201*crLHS632 + crLHS1208); + rLHS(23,21)+=gauss_weight*(DN_v(7,0)*crLHS239 + DN_v(7,1)*crLHS472 + DN_v(7,2)*crLHS633 - crLHS1199*crLHS637 - crLHS1201*crLHS637 + crLHS1212); + rLHS(23,22)+=gauss_weight*(DN_v(7,0)*crLHS256 + DN_v(7,1)*crLHS479 + DN_v(7,2)*crLHS638 - crLHS1199*crLHS641 - crLHS1201*crLHS641 + crLHS1228); + rLHS(23,23)+=gauss_weight*(DN_v(7,0)*crLHS264 + DN_v(7,1)*crLHS487 + std::pow(DN_v(7,2), 2)*crLHS9 + DN_v(7,2)*crLHS642 - crLHS1199*crLHS646 - crLHS1201*crLHS646 + crLHS1209); + rLHS(23,24)+=gauss_weight*(DN_v(7,0)*crLHS271 + DN_v(7,1)*crLHS491 + DN_v(7,2)*crLHS647 - crLHS1199*crLHS651 - crLHS1201*crLHS651 + crLHS1240); + rLHS(23,25)+=gauss_weight*(DN_v(7,0)*crLHS288 + DN_v(7,1)*crLHS498 + DN_v(7,2)*crLHS652 - crLHS1199*crLHS655 - crLHS1201*crLHS655 + crLHS1241); + rLHS(23,26)+=gauss_weight*(DN_v(7,0)*crLHS296 + DN_v(7,1)*crLHS506 + DN_v(7,2)*crLHS656 - crLHS1199*crLHS660 - crLHS1201*crLHS660 + crLHS1215 + crLHS1242); + rLHS(23,27)+=gauss_weight*(DN_v(7,0)*crLHS303 + DN_v(7,1)*crLHS510 + DN_v(7,2)*crLHS661 - crLHS1199*crLHS665 - crLHS1201*crLHS665 + crLHS1243); + rLHS(23,28)+=gauss_weight*(DN_v(7,0)*crLHS319 + DN_v(7,1)*crLHS517 + DN_v(7,2)*crLHS666 - crLHS1199*crLHS669 - crLHS1201*crLHS669 + crLHS1244); + rLHS(23,29)+=gauss_weight*(DN_v(7,0)*crLHS327 + DN_v(7,1)*crLHS525 + DN_v(7,2)*crLHS670 - crLHS1199*crLHS674 - crLHS1201*crLHS674 + crLHS1220 + crLHS1245); + rLHS(23,30)+=gauss_weight*(crLHS1200*crLHS676 + crLHS1246 + crLHS245*crLHS676); + rLHS(23,31)+=gauss_weight*(crLHS1200*crLHS678 + crLHS1247 + crLHS245*crLHS678); + rLHS(23,32)+=gauss_weight*(crLHS1200*crLHS680 + crLHS1248 + crLHS245*crLHS680); + rLHS(23,33)+=gauss_weight*(crLHS1200*crLHS682 + crLHS1249 + crLHS245*crLHS682); + rLHS(24,0)+=gauss_weight*(DN_v(8,0)*crLHS0 + DN_v(8,1)*crLHS2 + DN_v(8,2)*crLHS4 - crLHS1250*crLHS19 - crLHS1252*crLHS19 + crLHS1253 + crLHS272); + rLHS(24,1)+=gauss_weight*(DN_v(8,0)*crLHS26 + DN_v(8,1)*crLHS28 + DN_v(8,2)*crLHS31 - crLHS1250*crLHS35 - crLHS1252*crLHS35 + crLHS492); + rLHS(24,2)+=gauss_weight*(DN_v(8,0)*crLHS36 + DN_v(8,1)*crLHS38 + DN_v(8,2)*crLHS40 - crLHS1250*crLHS42 - crLHS1252*crLHS42 + crLHS648); + rLHS(24,3)+=gauss_weight*(DN_v(8,0)*crLHS43 + DN_v(8,1)*crLHS45 + DN_v(8,2)*crLHS47 - crLHS1250*crLHS56 - crLHS1252*crLHS56 + crLHS1254 + crLHS721); + rLHS(24,4)+=gauss_weight*(DN_v(8,0)*crLHS59 + DN_v(8,1)*crLHS61 + DN_v(8,2)*crLHS64 - crLHS1250*crLHS67 - crLHS1252*crLHS67 + crLHS755); + rLHS(24,5)+=gauss_weight*(DN_v(8,0)*crLHS68 + DN_v(8,1)*crLHS70 + DN_v(8,2)*crLHS72 - crLHS1250*crLHS74 - crLHS1252*crLHS74 + crLHS784); + rLHS(24,6)+=gauss_weight*(DN_v(8,0)*crLHS75 + DN_v(8,1)*crLHS77 + DN_v(8,2)*crLHS79 - crLHS1250*crLHS88 - crLHS1252*crLHS88 + crLHS1255 + crLHS828); + rLHS(24,7)+=gauss_weight*(DN_v(8,0)*crLHS91 + DN_v(8,1)*crLHS93 + DN_v(8,2)*crLHS96 - crLHS1250*crLHS99 - crLHS1252*crLHS99 + crLHS859); + rLHS(24,8)+=gauss_weight*(DN_v(8,0)*crLHS100 + DN_v(8,1)*crLHS102 + DN_v(8,2)*crLHS104 - crLHS106*crLHS1250 - crLHS106*crLHS1252 + crLHS885); + rLHS(24,9)+=gauss_weight*(DN_v(8,0)*crLHS107 + DN_v(8,1)*crLHS109 + DN_v(8,2)*crLHS111 - crLHS120*crLHS1250 - crLHS120*crLHS1252 + crLHS1256 + crLHS925); + rLHS(24,10)+=gauss_weight*(DN_v(8,0)*crLHS123 + DN_v(8,1)*crLHS125 + DN_v(8,2)*crLHS128 - crLHS1250*crLHS131 - crLHS1252*crLHS131 + crLHS953); + rLHS(24,11)+=gauss_weight*(DN_v(8,0)*crLHS132 + DN_v(8,1)*crLHS134 + DN_v(8,2)*crLHS136 - crLHS1250*crLHS138 - crLHS1252*crLHS138 + crLHS976); + rLHS(24,12)+=gauss_weight*(DN_v(8,0)*crLHS139 + DN_v(8,1)*crLHS141 + DN_v(8,2)*crLHS143 + crLHS1012 - crLHS1250*crLHS152 - crLHS1252*crLHS152 + crLHS1257); + rLHS(24,13)+=gauss_weight*(DN_v(8,0)*crLHS155 + DN_v(8,1)*crLHS157 + DN_v(8,2)*crLHS160 + crLHS1037 - crLHS1250*crLHS163 - crLHS1252*crLHS163); + rLHS(24,14)+=gauss_weight*(DN_v(8,0)*crLHS164 + DN_v(8,1)*crLHS166 + DN_v(8,2)*crLHS168 + crLHS1057 - crLHS1250*crLHS170 - crLHS1252*crLHS170); + rLHS(24,15)+=gauss_weight*(DN_v(8,0)*crLHS171 + DN_v(8,1)*crLHS173 + DN_v(8,2)*crLHS175 + crLHS1089 - crLHS1250*crLHS184 - crLHS1252*crLHS184 + crLHS1258); + rLHS(24,16)+=gauss_weight*(DN_v(8,0)*crLHS187 + DN_v(8,1)*crLHS189 + DN_v(8,2)*crLHS192 + crLHS1111 - crLHS1250*crLHS195 - crLHS1252*crLHS195); + rLHS(24,17)+=gauss_weight*(DN_v(8,0)*crLHS196 + DN_v(8,1)*crLHS198 + DN_v(8,2)*crLHS200 + crLHS1128 - crLHS1250*crLHS202 - crLHS1252*crLHS202); + rLHS(24,18)+=gauss_weight*(DN_v(8,0)*crLHS203 + DN_v(8,1)*crLHS205 + DN_v(8,2)*crLHS207 + crLHS1156 - crLHS1250*crLHS216 - crLHS1252*crLHS216 + crLHS1259); + rLHS(24,19)+=gauss_weight*(DN_v(8,0)*crLHS219 + DN_v(8,1)*crLHS221 + DN_v(8,2)*crLHS224 + crLHS1175 - crLHS1250*crLHS227 - crLHS1252*crLHS227); + rLHS(24,20)+=gauss_weight*(DN_v(8,0)*crLHS228 + DN_v(8,1)*crLHS230 + DN_v(8,2)*crLHS232 + crLHS1189 - crLHS1250*crLHS234 - crLHS1252*crLHS234); + rLHS(24,21)+=gauss_weight*(DN_v(8,0)*crLHS235 + DN_v(8,1)*crLHS237 + DN_v(8,2)*crLHS239 + crLHS1213 - crLHS1250*crLHS248 - crLHS1252*crLHS248 + crLHS1260); + rLHS(24,22)+=gauss_weight*(DN_v(8,0)*crLHS251 + DN_v(8,1)*crLHS253 + DN_v(8,2)*crLHS256 + crLHS1229 - crLHS1250*crLHS259 - crLHS1252*crLHS259); + rLHS(24,23)+=gauss_weight*(DN_v(8,0)*crLHS260 + DN_v(8,1)*crLHS262 + DN_v(8,2)*crLHS264 + crLHS1240 - crLHS1250*crLHS266 - crLHS1252*crLHS266); + rLHS(24,24)+=gauss_weight*(std::pow(DN_v(8,0), 2)*crLHS9 + DN_v(8,0)*crLHS267 + DN_v(8,1)*crLHS269 + DN_v(8,2)*crLHS271 - crLHS1250*crLHS280 - crLHS1252*crLHS280 + crLHS1261); + rLHS(24,25)+=gauss_weight*(DN_v(8,0)*crLHS283 + DN_v(8,1)*crLHS285 + DN_v(8,2)*crLHS288 - crLHS1250*crLHS291 - crLHS1252*crLHS291 + crLHS1263); + rLHS(24,26)+=gauss_weight*(DN_v(8,0)*crLHS292 + DN_v(8,1)*crLHS294 + DN_v(8,2)*crLHS296 - crLHS1250*crLHS298 - crLHS1252*crLHS298 + crLHS1264); + rLHS(24,27)+=gauss_weight*(DN_v(8,0)*crLHS299 + DN_v(8,1)*crLHS301 + DN_v(8,2)*crLHS303 - crLHS1250*crLHS311 - crLHS1252*crLHS311 + crLHS1265 + crLHS1267); + rLHS(24,28)+=gauss_weight*(DN_v(8,0)*crLHS314 + DN_v(8,1)*crLHS316 + DN_v(8,2)*crLHS319 - crLHS1250*crLHS322 - crLHS1252*crLHS322 + crLHS1268); + rLHS(24,29)+=gauss_weight*(DN_v(8,0)*crLHS323 + DN_v(8,1)*crLHS325 + DN_v(8,2)*crLHS327 - crLHS1250*crLHS329 - crLHS1252*crLHS329 + crLHS1269); + rLHS(24,30)+=gauss_weight*(crLHS1251*crLHS331 + crLHS1270 + crLHS277*crLHS331); + rLHS(24,31)+=gauss_weight*(crLHS1251*crLHS333 + crLHS1271 + crLHS277*crLHS333); + rLHS(24,32)+=gauss_weight*(crLHS1251*crLHS335 + crLHS1272 + crLHS277*crLHS335); + rLHS(24,33)+=gauss_weight*(crLHS1251*crLHS337 + crLHS1273 + crLHS277*crLHS337); + rLHS(25,0)+=gauss_weight*(DN_v(8,0)*crLHS2 + DN_v(8,1)*crLHS338 + DN_v(8,2)*crLHS339 - crLHS1250*crLHS342 - crLHS1252*crLHS342 + crLHS289); + rLHS(25,1)+=gauss_weight*(DN_v(8,0)*crLHS28 + DN_v(8,1)*crLHS343 + DN_v(8,2)*crLHS345 - crLHS1250*crLHS350 - crLHS1252*crLHS350 + crLHS1253 + crLHS499); + rLHS(25,2)+=gauss_weight*(DN_v(8,0)*crLHS38 + DN_v(8,1)*crLHS351 + DN_v(8,2)*crLHS353 - crLHS1250*crLHS356 - crLHS1252*crLHS356 + crLHS653); + rLHS(25,3)+=gauss_weight*(DN_v(8,0)*crLHS45 + DN_v(8,1)*crLHS357 + DN_v(8,2)*crLHS358 - crLHS1250*crLHS362 - crLHS1252*crLHS362 + crLHS724); + rLHS(25,4)+=gauss_weight*(DN_v(8,0)*crLHS61 + DN_v(8,1)*crLHS363 + DN_v(8,2)*crLHS365 - crLHS1250*crLHS370 - crLHS1252*crLHS370 + crLHS1254 + crLHS756); + rLHS(25,5)+=gauss_weight*(DN_v(8,0)*crLHS70 + DN_v(8,1)*crLHS371 + DN_v(8,2)*crLHS373 - crLHS1250*crLHS375 - crLHS1252*crLHS375 + crLHS785); + rLHS(25,6)+=gauss_weight*(DN_v(8,0)*crLHS77 + DN_v(8,1)*crLHS376 + DN_v(8,2)*crLHS377 - crLHS1250*crLHS381 - crLHS1252*crLHS381 + crLHS831); + rLHS(25,7)+=gauss_weight*(DN_v(8,0)*crLHS93 + DN_v(8,1)*crLHS382 + DN_v(8,2)*crLHS384 - crLHS1250*crLHS389 - crLHS1252*crLHS389 + crLHS1255 + crLHS860); + rLHS(25,8)+=gauss_weight*(DN_v(8,0)*crLHS102 + DN_v(8,1)*crLHS390 + DN_v(8,2)*crLHS392 - crLHS1250*crLHS394 - crLHS1252*crLHS394 + crLHS886); + rLHS(25,9)+=gauss_weight*(DN_v(8,0)*crLHS109 + DN_v(8,1)*crLHS395 + DN_v(8,2)*crLHS396 - crLHS1250*crLHS400 - crLHS1252*crLHS400 + crLHS928); + rLHS(25,10)+=gauss_weight*(DN_v(8,0)*crLHS125 + DN_v(8,1)*crLHS401 + DN_v(8,2)*crLHS403 - crLHS1250*crLHS408 - crLHS1252*crLHS408 + crLHS1256 + crLHS954); + rLHS(25,11)+=gauss_weight*(DN_v(8,0)*crLHS134 + DN_v(8,1)*crLHS409 + DN_v(8,2)*crLHS411 - crLHS1250*crLHS413 - crLHS1252*crLHS413 + crLHS977); + rLHS(25,12)+=gauss_weight*(DN_v(8,0)*crLHS141 + DN_v(8,1)*crLHS414 + DN_v(8,2)*crLHS415 + crLHS1015 - crLHS1250*crLHS419 - crLHS1252*crLHS419); + rLHS(25,13)+=gauss_weight*(DN_v(8,0)*crLHS157 + DN_v(8,1)*crLHS420 + DN_v(8,2)*crLHS422 + crLHS1038 - crLHS1250*crLHS427 - crLHS1252*crLHS427 + crLHS1257); + rLHS(25,14)+=gauss_weight*(DN_v(8,0)*crLHS166 + DN_v(8,1)*crLHS428 + DN_v(8,2)*crLHS430 + crLHS1058 - crLHS1250*crLHS432 - crLHS1252*crLHS432); + rLHS(25,15)+=gauss_weight*(DN_v(8,0)*crLHS173 + DN_v(8,1)*crLHS433 + DN_v(8,2)*crLHS434 + crLHS1092 - crLHS1250*crLHS438 - crLHS1252*crLHS438); + rLHS(25,16)+=gauss_weight*(DN_v(8,0)*crLHS189 + DN_v(8,1)*crLHS439 + DN_v(8,2)*crLHS441 + crLHS1112 - crLHS1250*crLHS446 - crLHS1252*crLHS446 + crLHS1258); + rLHS(25,17)+=gauss_weight*(DN_v(8,0)*crLHS198 + DN_v(8,1)*crLHS447 + DN_v(8,2)*crLHS449 + crLHS1129 - crLHS1250*crLHS451 - crLHS1252*crLHS451); + rLHS(25,18)+=gauss_weight*(DN_v(8,0)*crLHS205 + DN_v(8,1)*crLHS452 + DN_v(8,2)*crLHS453 + crLHS1159 - crLHS1250*crLHS457 - crLHS1252*crLHS457); + rLHS(25,19)+=gauss_weight*(DN_v(8,0)*crLHS221 + DN_v(8,1)*crLHS458 + DN_v(8,2)*crLHS460 + crLHS1176 - crLHS1250*crLHS465 - crLHS1252*crLHS465 + crLHS1259); + rLHS(25,20)+=gauss_weight*(DN_v(8,0)*crLHS230 + DN_v(8,1)*crLHS466 + DN_v(8,2)*crLHS468 + crLHS1190 - crLHS1250*crLHS470 - crLHS1252*crLHS470); + rLHS(25,21)+=gauss_weight*(DN_v(8,0)*crLHS237 + DN_v(8,1)*crLHS471 + DN_v(8,2)*crLHS472 + crLHS1216 - crLHS1250*crLHS476 - crLHS1252*crLHS476); + rLHS(25,22)+=gauss_weight*(DN_v(8,0)*crLHS253 + DN_v(8,1)*crLHS477 + DN_v(8,2)*crLHS479 + crLHS1230 - crLHS1250*crLHS484 - crLHS1252*crLHS484 + crLHS1260); + rLHS(25,23)+=gauss_weight*(DN_v(8,0)*crLHS262 + DN_v(8,1)*crLHS485 + DN_v(8,2)*crLHS487 + crLHS1241 - crLHS1250*crLHS489 - crLHS1252*crLHS489); + rLHS(25,24)+=gauss_weight*(DN_v(8,0)*crLHS269 + DN_v(8,1)*crLHS490 + DN_v(8,2)*crLHS491 - crLHS1250*crLHS495 - crLHS1252*crLHS495 + crLHS1263); + rLHS(25,25)+=gauss_weight*(DN_v(8,0)*crLHS285 + std::pow(DN_v(8,1), 2)*crLHS9 + DN_v(8,1)*crLHS496 + DN_v(8,2)*crLHS498 - crLHS1250*crLHS503 - crLHS1252*crLHS503 + crLHS1261); + rLHS(25,26)+=gauss_weight*(DN_v(8,0)*crLHS294 + DN_v(8,1)*crLHS504 + DN_v(8,2)*crLHS506 - crLHS1250*crLHS508 - crLHS1252*crLHS508 + crLHS1275); + rLHS(25,27)+=gauss_weight*(DN_v(8,0)*crLHS301 + DN_v(8,1)*crLHS509 + DN_v(8,2)*crLHS510 - crLHS1250*crLHS514 - crLHS1252*crLHS514 + crLHS1276); + rLHS(25,28)+=gauss_weight*(DN_v(8,0)*crLHS316 + DN_v(8,1)*crLHS515 + DN_v(8,2)*crLHS517 - crLHS1250*crLHS522 - crLHS1252*crLHS522 + crLHS1267 + crLHS1277); + rLHS(25,29)+=gauss_weight*(DN_v(8,0)*crLHS325 + DN_v(8,1)*crLHS523 + DN_v(8,2)*crLHS525 - crLHS1250*crLHS527 - crLHS1252*crLHS527 + crLHS1278); + rLHS(25,30)+=gauss_weight*(crLHS1251*crLHS529 + crLHS1279 + crLHS277*crLHS529); + rLHS(25,31)+=gauss_weight*(crLHS1251*crLHS531 + crLHS1280 + crLHS277*crLHS531); + rLHS(25,32)+=gauss_weight*(crLHS1251*crLHS533 + crLHS1281 + crLHS277*crLHS533); + rLHS(25,33)+=gauss_weight*(crLHS1251*crLHS535 + crLHS1282 + crLHS277*crLHS535); + rLHS(26,0)+=gauss_weight*(DN_v(8,0)*crLHS4 + DN_v(8,1)*crLHS339 + DN_v(8,2)*crLHS536 - crLHS1250*crLHS539 - crLHS1252*crLHS539 + crLHS297); + rLHS(26,1)+=gauss_weight*(DN_v(8,0)*crLHS31 + DN_v(8,1)*crLHS345 + DN_v(8,2)*crLHS540 - crLHS1250*crLHS542 - crLHS1252*crLHS542 + crLHS507); + rLHS(26,2)+=gauss_weight*(DN_v(8,0)*crLHS40 + DN_v(8,1)*crLHS353 + DN_v(8,2)*crLHS543 - crLHS1250*crLHS547 - crLHS1252*crLHS547 + crLHS1253 + crLHS657); + rLHS(26,3)+=gauss_weight*(DN_v(8,0)*crLHS47 + DN_v(8,1)*crLHS358 + DN_v(8,2)*crLHS548 - crLHS1250*crLHS553 - crLHS1252*crLHS553 + crLHS725); + rLHS(26,4)+=gauss_weight*(DN_v(8,0)*crLHS64 + DN_v(8,1)*crLHS365 + DN_v(8,2)*crLHS554 - crLHS1250*crLHS557 - crLHS1252*crLHS557 + crLHS757); + rLHS(26,5)+=gauss_weight*(DN_v(8,0)*crLHS72 + DN_v(8,1)*crLHS373 + DN_v(8,2)*crLHS558 - crLHS1250*crLHS562 - crLHS1252*crLHS562 + crLHS1254 + crLHS786); + rLHS(26,6)+=gauss_weight*(DN_v(8,0)*crLHS79 + DN_v(8,1)*crLHS377 + DN_v(8,2)*crLHS563 - crLHS1250*crLHS567 - crLHS1252*crLHS567 + crLHS832); + rLHS(26,7)+=gauss_weight*(DN_v(8,0)*crLHS96 + DN_v(8,1)*crLHS384 + DN_v(8,2)*crLHS568 - crLHS1250*crLHS571 - crLHS1252*crLHS571 + crLHS861); + rLHS(26,8)+=gauss_weight*(DN_v(8,0)*crLHS104 + DN_v(8,1)*crLHS392 + DN_v(8,2)*crLHS572 - crLHS1250*crLHS576 - crLHS1252*crLHS576 + crLHS1255 + crLHS887); + rLHS(26,9)+=gauss_weight*(DN_v(8,0)*crLHS111 + DN_v(8,1)*crLHS396 + DN_v(8,2)*crLHS577 - crLHS1250*crLHS581 - crLHS1252*crLHS581 + crLHS929); + rLHS(26,10)+=gauss_weight*(DN_v(8,0)*crLHS128 + DN_v(8,1)*crLHS403 + DN_v(8,2)*crLHS582 - crLHS1250*crLHS585 - crLHS1252*crLHS585 + crLHS955); + rLHS(26,11)+=gauss_weight*(DN_v(8,0)*crLHS136 + DN_v(8,1)*crLHS411 + DN_v(8,2)*crLHS586 - crLHS1250*crLHS590 - crLHS1252*crLHS590 + crLHS1256 + crLHS978); + rLHS(26,12)+=gauss_weight*(DN_v(8,0)*crLHS143 + DN_v(8,1)*crLHS415 + DN_v(8,2)*crLHS591 + crLHS1016 - crLHS1250*crLHS595 - crLHS1252*crLHS595); + rLHS(26,13)+=gauss_weight*(DN_v(8,0)*crLHS160 + DN_v(8,1)*crLHS422 + DN_v(8,2)*crLHS596 + crLHS1039 - crLHS1250*crLHS599 - crLHS1252*crLHS599); + rLHS(26,14)+=gauss_weight*(DN_v(8,0)*crLHS168 + DN_v(8,1)*crLHS430 + DN_v(8,2)*crLHS600 + crLHS1059 - crLHS1250*crLHS604 - crLHS1252*crLHS604 + crLHS1257); + rLHS(26,15)+=gauss_weight*(DN_v(8,0)*crLHS175 + DN_v(8,1)*crLHS434 + DN_v(8,2)*crLHS605 + crLHS1093 - crLHS1250*crLHS609 - crLHS1252*crLHS609); + rLHS(26,16)+=gauss_weight*(DN_v(8,0)*crLHS192 + DN_v(8,1)*crLHS441 + DN_v(8,2)*crLHS610 + crLHS1113 - crLHS1250*crLHS613 - crLHS1252*crLHS613); + rLHS(26,17)+=gauss_weight*(DN_v(8,0)*crLHS200 + DN_v(8,1)*crLHS449 + DN_v(8,2)*crLHS614 + crLHS1130 - crLHS1250*crLHS618 - crLHS1252*crLHS618 + crLHS1258); + rLHS(26,18)+=gauss_weight*(DN_v(8,0)*crLHS207 + DN_v(8,1)*crLHS453 + DN_v(8,2)*crLHS619 + crLHS1160 - crLHS1250*crLHS623 - crLHS1252*crLHS623); + rLHS(26,19)+=gauss_weight*(DN_v(8,0)*crLHS224 + DN_v(8,1)*crLHS460 + DN_v(8,2)*crLHS624 + crLHS1177 - crLHS1250*crLHS627 - crLHS1252*crLHS627); + rLHS(26,20)+=gauss_weight*(DN_v(8,0)*crLHS232 + DN_v(8,1)*crLHS468 + DN_v(8,2)*crLHS628 + crLHS1191 - crLHS1250*crLHS632 - crLHS1252*crLHS632 + crLHS1259); + rLHS(26,21)+=gauss_weight*(DN_v(8,0)*crLHS239 + DN_v(8,1)*crLHS472 + DN_v(8,2)*crLHS633 + crLHS1217 - crLHS1250*crLHS637 - crLHS1252*crLHS637); + rLHS(26,22)+=gauss_weight*(DN_v(8,0)*crLHS256 + DN_v(8,1)*crLHS479 + DN_v(8,2)*crLHS638 + crLHS1231 - crLHS1250*crLHS641 - crLHS1252*crLHS641); + rLHS(26,23)+=gauss_weight*(DN_v(8,0)*crLHS264 + DN_v(8,1)*crLHS487 + DN_v(8,2)*crLHS642 + crLHS1242 - crLHS1250*crLHS646 - crLHS1252*crLHS646 + crLHS1260); + rLHS(26,24)+=gauss_weight*(DN_v(8,0)*crLHS271 + DN_v(8,1)*crLHS491 + DN_v(8,2)*crLHS647 - crLHS1250*crLHS651 - crLHS1252*crLHS651 + crLHS1264); + rLHS(26,25)+=gauss_weight*(DN_v(8,0)*crLHS288 + DN_v(8,1)*crLHS498 + DN_v(8,2)*crLHS652 - crLHS1250*crLHS655 - crLHS1252*crLHS655 + crLHS1275); + rLHS(26,26)+=gauss_weight*(DN_v(8,0)*crLHS296 + DN_v(8,1)*crLHS506 + std::pow(DN_v(8,2), 2)*crLHS9 + DN_v(8,2)*crLHS656 - crLHS1250*crLHS660 - crLHS1252*crLHS660 + crLHS1261); + rLHS(26,27)+=gauss_weight*(DN_v(8,0)*crLHS303 + DN_v(8,1)*crLHS510 + DN_v(8,2)*crLHS661 - crLHS1250*crLHS665 - crLHS1252*crLHS665 + crLHS1284); + rLHS(26,28)+=gauss_weight*(DN_v(8,0)*crLHS319 + DN_v(8,1)*crLHS517 + DN_v(8,2)*crLHS666 - crLHS1250*crLHS669 - crLHS1252*crLHS669 + crLHS1285); + rLHS(26,29)+=gauss_weight*(DN_v(8,0)*crLHS327 + DN_v(8,1)*crLHS525 + DN_v(8,2)*crLHS670 - crLHS1250*crLHS674 - crLHS1252*crLHS674 + crLHS1267 + crLHS1286); + rLHS(26,30)+=gauss_weight*(crLHS1251*crLHS676 + crLHS1287 + crLHS277*crLHS676); + rLHS(26,31)+=gauss_weight*(crLHS1251*crLHS678 + crLHS1288 + crLHS277*crLHS678); + rLHS(26,32)+=gauss_weight*(crLHS1251*crLHS680 + crLHS1289 + crLHS277*crLHS680); + rLHS(26,33)+=gauss_weight*(crLHS1251*crLHS682 + crLHS1290 + crLHS277*crLHS682); + rLHS(27,0)+=gauss_weight*(DN_v(9,0)*crLHS0 + DN_v(9,1)*crLHS2 + DN_v(9,2)*crLHS4 - crLHS1291*crLHS19 - crLHS1293*crLHS19 + crLHS1294 + crLHS304); + rLHS(27,1)+=gauss_weight*(DN_v(9,0)*crLHS26 + DN_v(9,1)*crLHS28 + DN_v(9,2)*crLHS31 - crLHS1291*crLHS35 - crLHS1293*crLHS35 + crLHS511); + rLHS(27,2)+=gauss_weight*(DN_v(9,0)*crLHS36 + DN_v(9,1)*crLHS38 + DN_v(9,2)*crLHS40 - crLHS1291*crLHS42 - crLHS1293*crLHS42 + crLHS662); + rLHS(27,3)+=gauss_weight*(DN_v(9,0)*crLHS43 + DN_v(9,1)*crLHS45 + DN_v(9,2)*crLHS47 - crLHS1291*crLHS56 - crLHS1293*crLHS56 + crLHS1295 + crLHS726); + rLHS(27,4)+=gauss_weight*(DN_v(9,0)*crLHS59 + DN_v(9,1)*crLHS61 + DN_v(9,2)*crLHS64 - crLHS1291*crLHS67 - crLHS1293*crLHS67 + crLHS758); + rLHS(27,5)+=gauss_weight*(DN_v(9,0)*crLHS68 + DN_v(9,1)*crLHS70 + DN_v(9,2)*crLHS72 - crLHS1291*crLHS74 - crLHS1293*crLHS74 + crLHS787); + rLHS(27,6)+=gauss_weight*(DN_v(9,0)*crLHS75 + DN_v(9,1)*crLHS77 + DN_v(9,2)*crLHS79 - crLHS1291*crLHS88 - crLHS1293*crLHS88 + crLHS1296 + crLHS833); + rLHS(27,7)+=gauss_weight*(DN_v(9,0)*crLHS91 + DN_v(9,1)*crLHS93 + DN_v(9,2)*crLHS96 - crLHS1291*crLHS99 - crLHS1293*crLHS99 + crLHS862); + rLHS(27,8)+=gauss_weight*(DN_v(9,0)*crLHS100 + DN_v(9,1)*crLHS102 + DN_v(9,2)*crLHS104 - crLHS106*crLHS1291 - crLHS106*crLHS1293 + crLHS888); + rLHS(27,9)+=gauss_weight*(DN_v(9,0)*crLHS107 + DN_v(9,1)*crLHS109 + DN_v(9,2)*crLHS111 - crLHS120*crLHS1291 - crLHS120*crLHS1293 + crLHS1297 + crLHS930); + rLHS(27,10)+=gauss_weight*(DN_v(9,0)*crLHS123 + DN_v(9,1)*crLHS125 + DN_v(9,2)*crLHS128 - crLHS1291*crLHS131 - crLHS1293*crLHS131 + crLHS956); + rLHS(27,11)+=gauss_weight*(DN_v(9,0)*crLHS132 + DN_v(9,1)*crLHS134 + DN_v(9,2)*crLHS136 - crLHS1291*crLHS138 - crLHS1293*crLHS138 + crLHS979); + rLHS(27,12)+=gauss_weight*(DN_v(9,0)*crLHS139 + DN_v(9,1)*crLHS141 + DN_v(9,2)*crLHS143 + crLHS1017 - crLHS1291*crLHS152 - crLHS1293*crLHS152 + crLHS1298); + rLHS(27,13)+=gauss_weight*(DN_v(9,0)*crLHS155 + DN_v(9,1)*crLHS157 + DN_v(9,2)*crLHS160 + crLHS1040 - crLHS1291*crLHS163 - crLHS1293*crLHS163); + rLHS(27,14)+=gauss_weight*(DN_v(9,0)*crLHS164 + DN_v(9,1)*crLHS166 + DN_v(9,2)*crLHS168 + crLHS1060 - crLHS1291*crLHS170 - crLHS1293*crLHS170); + rLHS(27,15)+=gauss_weight*(DN_v(9,0)*crLHS171 + DN_v(9,1)*crLHS173 + DN_v(9,2)*crLHS175 + crLHS1094 - crLHS1291*crLHS184 - crLHS1293*crLHS184 + crLHS1299); + rLHS(27,16)+=gauss_weight*(DN_v(9,0)*crLHS187 + DN_v(9,1)*crLHS189 + DN_v(9,2)*crLHS192 + crLHS1114 - crLHS1291*crLHS195 - crLHS1293*crLHS195); + rLHS(27,17)+=gauss_weight*(DN_v(9,0)*crLHS196 + DN_v(9,1)*crLHS198 + DN_v(9,2)*crLHS200 + crLHS1131 - crLHS1291*crLHS202 - crLHS1293*crLHS202); + rLHS(27,18)+=gauss_weight*(DN_v(9,0)*crLHS203 + DN_v(9,1)*crLHS205 + DN_v(9,2)*crLHS207 + crLHS1161 - crLHS1291*crLHS216 - crLHS1293*crLHS216 + crLHS1300); + rLHS(27,19)+=gauss_weight*(DN_v(9,0)*crLHS219 + DN_v(9,1)*crLHS221 + DN_v(9,2)*crLHS224 + crLHS1178 - crLHS1291*crLHS227 - crLHS1293*crLHS227); + rLHS(27,20)+=gauss_weight*(DN_v(9,0)*crLHS228 + DN_v(9,1)*crLHS230 + DN_v(9,2)*crLHS232 + crLHS1192 - crLHS1291*crLHS234 - crLHS1293*crLHS234); + rLHS(27,21)+=gauss_weight*(DN_v(9,0)*crLHS235 + DN_v(9,1)*crLHS237 + DN_v(9,2)*crLHS239 + crLHS1218 - crLHS1291*crLHS248 - crLHS1293*crLHS248 + crLHS1301); + rLHS(27,22)+=gauss_weight*(DN_v(9,0)*crLHS251 + DN_v(9,1)*crLHS253 + DN_v(9,2)*crLHS256 + crLHS1232 - crLHS1291*crLHS259 - crLHS1293*crLHS259); + rLHS(27,23)+=gauss_weight*(DN_v(9,0)*crLHS260 + DN_v(9,1)*crLHS262 + DN_v(9,2)*crLHS264 + crLHS1243 - crLHS1291*crLHS266 - crLHS1293*crLHS266); + rLHS(27,24)+=gauss_weight*(DN_v(9,0)*crLHS267 + DN_v(9,1)*crLHS269 + DN_v(9,2)*crLHS271 + crLHS1265 - crLHS1291*crLHS280 - crLHS1293*crLHS280 + crLHS1302); + rLHS(27,25)+=gauss_weight*(DN_v(9,0)*crLHS283 + DN_v(9,1)*crLHS285 + DN_v(9,2)*crLHS288 + crLHS1276 - crLHS1291*crLHS291 - crLHS1293*crLHS291); + rLHS(27,26)+=gauss_weight*(DN_v(9,0)*crLHS292 + DN_v(9,1)*crLHS294 + DN_v(9,2)*crLHS296 + crLHS1284 - crLHS1291*crLHS298 - crLHS1293*crLHS298); + rLHS(27,27)+=gauss_weight*(std::pow(DN_v(9,0), 2)*crLHS9 + DN_v(9,0)*crLHS299 + DN_v(9,1)*crLHS301 + DN_v(9,2)*crLHS303 - crLHS1291*crLHS311 - crLHS1293*crLHS311 + crLHS1303); + rLHS(27,28)+=gauss_weight*(DN_v(9,0)*crLHS314 + DN_v(9,1)*crLHS316 + DN_v(9,2)*crLHS319 - crLHS1291*crLHS322 - crLHS1293*crLHS322 + crLHS1305); + rLHS(27,29)+=gauss_weight*(DN_v(9,0)*crLHS323 + DN_v(9,1)*crLHS325 + DN_v(9,2)*crLHS327 - crLHS1291*crLHS329 - crLHS1293*crLHS329 + crLHS1306); + rLHS(27,30)+=gauss_weight*(crLHS1292*crLHS331 + crLHS1307 + crLHS309*crLHS331); + rLHS(27,31)+=gauss_weight*(crLHS1292*crLHS333 + crLHS1308 + crLHS309*crLHS333); + rLHS(27,32)+=gauss_weight*(crLHS1292*crLHS335 + crLHS1309 + crLHS309*crLHS335); + rLHS(27,33)+=gauss_weight*(crLHS1292*crLHS337 + crLHS1310 + crLHS309*crLHS337); + rLHS(28,0)+=gauss_weight*(DN_v(9,0)*crLHS2 + DN_v(9,1)*crLHS338 + DN_v(9,2)*crLHS339 - crLHS1291*crLHS342 - crLHS1293*crLHS342 + crLHS320); + rLHS(28,1)+=gauss_weight*(DN_v(9,0)*crLHS28 + DN_v(9,1)*crLHS343 + DN_v(9,2)*crLHS345 - crLHS1291*crLHS350 - crLHS1293*crLHS350 + crLHS1294 + crLHS518); + rLHS(28,2)+=gauss_weight*(DN_v(9,0)*crLHS38 + DN_v(9,1)*crLHS351 + DN_v(9,2)*crLHS353 - crLHS1291*crLHS356 - crLHS1293*crLHS356 + crLHS667); + rLHS(28,3)+=gauss_weight*(DN_v(9,0)*crLHS45 + DN_v(9,1)*crLHS357 + DN_v(9,2)*crLHS358 - crLHS1291*crLHS362 - crLHS1293*crLHS362 + crLHS729); + rLHS(28,4)+=gauss_weight*(DN_v(9,0)*crLHS61 + DN_v(9,1)*crLHS363 + DN_v(9,2)*crLHS365 - crLHS1291*crLHS370 - crLHS1293*crLHS370 + crLHS1295 + crLHS759); + rLHS(28,5)+=gauss_weight*(DN_v(9,0)*crLHS70 + DN_v(9,1)*crLHS371 + DN_v(9,2)*crLHS373 - crLHS1291*crLHS375 - crLHS1293*crLHS375 + crLHS788); + rLHS(28,6)+=gauss_weight*(DN_v(9,0)*crLHS77 + DN_v(9,1)*crLHS376 + DN_v(9,2)*crLHS377 - crLHS1291*crLHS381 - crLHS1293*crLHS381 + crLHS836); + rLHS(28,7)+=gauss_weight*(DN_v(9,0)*crLHS93 + DN_v(9,1)*crLHS382 + DN_v(9,2)*crLHS384 - crLHS1291*crLHS389 - crLHS1293*crLHS389 + crLHS1296 + crLHS863); + rLHS(28,8)+=gauss_weight*(DN_v(9,0)*crLHS102 + DN_v(9,1)*crLHS390 + DN_v(9,2)*crLHS392 - crLHS1291*crLHS394 - crLHS1293*crLHS394 + crLHS889); + rLHS(28,9)+=gauss_weight*(DN_v(9,0)*crLHS109 + DN_v(9,1)*crLHS395 + DN_v(9,2)*crLHS396 - crLHS1291*crLHS400 - crLHS1293*crLHS400 + crLHS933); + rLHS(28,10)+=gauss_weight*(DN_v(9,0)*crLHS125 + DN_v(9,1)*crLHS401 + DN_v(9,2)*crLHS403 - crLHS1291*crLHS408 - crLHS1293*crLHS408 + crLHS1297 + crLHS957); + rLHS(28,11)+=gauss_weight*(DN_v(9,0)*crLHS134 + DN_v(9,1)*crLHS409 + DN_v(9,2)*crLHS411 - crLHS1291*crLHS413 - crLHS1293*crLHS413 + crLHS980); + rLHS(28,12)+=gauss_weight*(DN_v(9,0)*crLHS141 + DN_v(9,1)*crLHS414 + DN_v(9,2)*crLHS415 + crLHS1020 - crLHS1291*crLHS419 - crLHS1293*crLHS419); + rLHS(28,13)+=gauss_weight*(DN_v(9,0)*crLHS157 + DN_v(9,1)*crLHS420 + DN_v(9,2)*crLHS422 + crLHS1041 - crLHS1291*crLHS427 - crLHS1293*crLHS427 + crLHS1298); + rLHS(28,14)+=gauss_weight*(DN_v(9,0)*crLHS166 + DN_v(9,1)*crLHS428 + DN_v(9,2)*crLHS430 + crLHS1061 - crLHS1291*crLHS432 - crLHS1293*crLHS432); + rLHS(28,15)+=gauss_weight*(DN_v(9,0)*crLHS173 + DN_v(9,1)*crLHS433 + DN_v(9,2)*crLHS434 + crLHS1097 - crLHS1291*crLHS438 - crLHS1293*crLHS438); + rLHS(28,16)+=gauss_weight*(DN_v(9,0)*crLHS189 + DN_v(9,1)*crLHS439 + DN_v(9,2)*crLHS441 + crLHS1115 - crLHS1291*crLHS446 - crLHS1293*crLHS446 + crLHS1299); + rLHS(28,17)+=gauss_weight*(DN_v(9,0)*crLHS198 + DN_v(9,1)*crLHS447 + DN_v(9,2)*crLHS449 + crLHS1132 - crLHS1291*crLHS451 - crLHS1293*crLHS451); + rLHS(28,18)+=gauss_weight*(DN_v(9,0)*crLHS205 + DN_v(9,1)*crLHS452 + DN_v(9,2)*crLHS453 + crLHS1164 - crLHS1291*crLHS457 - crLHS1293*crLHS457); + rLHS(28,19)+=gauss_weight*(DN_v(9,0)*crLHS221 + DN_v(9,1)*crLHS458 + DN_v(9,2)*crLHS460 + crLHS1179 - crLHS1291*crLHS465 - crLHS1293*crLHS465 + crLHS1300); + rLHS(28,20)+=gauss_weight*(DN_v(9,0)*crLHS230 + DN_v(9,1)*crLHS466 + DN_v(9,2)*crLHS468 + crLHS1193 - crLHS1291*crLHS470 - crLHS1293*crLHS470); + rLHS(28,21)+=gauss_weight*(DN_v(9,0)*crLHS237 + DN_v(9,1)*crLHS471 + DN_v(9,2)*crLHS472 + crLHS1221 - crLHS1291*crLHS476 - crLHS1293*crLHS476); + rLHS(28,22)+=gauss_weight*(DN_v(9,0)*crLHS253 + DN_v(9,1)*crLHS477 + DN_v(9,2)*crLHS479 + crLHS1233 - crLHS1291*crLHS484 - crLHS1293*crLHS484 + crLHS1301); + rLHS(28,23)+=gauss_weight*(DN_v(9,0)*crLHS262 + DN_v(9,1)*crLHS485 + DN_v(9,2)*crLHS487 + crLHS1244 - crLHS1291*crLHS489 - crLHS1293*crLHS489); + rLHS(28,24)+=gauss_weight*(DN_v(9,0)*crLHS269 + DN_v(9,1)*crLHS490 + DN_v(9,2)*crLHS491 + crLHS1268 - crLHS1291*crLHS495 - crLHS1293*crLHS495); + rLHS(28,25)+=gauss_weight*(DN_v(9,0)*crLHS285 + DN_v(9,1)*crLHS496 + DN_v(9,2)*crLHS498 + crLHS1277 - crLHS1291*crLHS503 - crLHS1293*crLHS503 + crLHS1302); + rLHS(28,26)+=gauss_weight*(DN_v(9,0)*crLHS294 + DN_v(9,1)*crLHS504 + DN_v(9,2)*crLHS506 + crLHS1285 - crLHS1291*crLHS508 - crLHS1293*crLHS508); + rLHS(28,27)+=gauss_weight*(DN_v(9,0)*crLHS301 + DN_v(9,1)*crLHS509 + DN_v(9,2)*crLHS510 - crLHS1291*crLHS514 - crLHS1293*crLHS514 + crLHS1305); + rLHS(28,28)+=gauss_weight*(DN_v(9,0)*crLHS316 + std::pow(DN_v(9,1), 2)*crLHS9 + DN_v(9,1)*crLHS515 + DN_v(9,2)*crLHS517 - crLHS1291*crLHS522 - crLHS1293*crLHS522 + crLHS1303); + rLHS(28,29)+=gauss_weight*(DN_v(9,0)*crLHS325 + DN_v(9,1)*crLHS523 + DN_v(9,2)*crLHS525 - crLHS1291*crLHS527 - crLHS1293*crLHS527 + crLHS1311); + rLHS(28,30)+=gauss_weight*(crLHS1292*crLHS529 + crLHS1312 + crLHS309*crLHS529); + rLHS(28,31)+=gauss_weight*(crLHS1292*crLHS531 + crLHS1313 + crLHS309*crLHS531); + rLHS(28,32)+=gauss_weight*(crLHS1292*crLHS533 + crLHS1314 + crLHS309*crLHS533); + rLHS(28,33)+=gauss_weight*(crLHS1292*crLHS535 + crLHS1315 + crLHS309*crLHS535); + rLHS(29,0)+=gauss_weight*(DN_v(9,0)*crLHS4 + DN_v(9,1)*crLHS339 + DN_v(9,2)*crLHS536 - crLHS1291*crLHS539 - crLHS1293*crLHS539 + crLHS328); + rLHS(29,1)+=gauss_weight*(DN_v(9,0)*crLHS31 + DN_v(9,1)*crLHS345 + DN_v(9,2)*crLHS540 - crLHS1291*crLHS542 - crLHS1293*crLHS542 + crLHS526); + rLHS(29,2)+=gauss_weight*(DN_v(9,0)*crLHS40 + DN_v(9,1)*crLHS353 + DN_v(9,2)*crLHS543 - crLHS1291*crLHS547 - crLHS1293*crLHS547 + crLHS1294 + crLHS671); + rLHS(29,3)+=gauss_weight*(DN_v(9,0)*crLHS47 + DN_v(9,1)*crLHS358 + DN_v(9,2)*crLHS548 - crLHS1291*crLHS553 - crLHS1293*crLHS553 + crLHS730); + rLHS(29,4)+=gauss_weight*(DN_v(9,0)*crLHS64 + DN_v(9,1)*crLHS365 + DN_v(9,2)*crLHS554 - crLHS1291*crLHS557 - crLHS1293*crLHS557 + crLHS760); + rLHS(29,5)+=gauss_weight*(DN_v(9,0)*crLHS72 + DN_v(9,1)*crLHS373 + DN_v(9,2)*crLHS558 - crLHS1291*crLHS562 - crLHS1293*crLHS562 + crLHS1295 + crLHS789); + rLHS(29,6)+=gauss_weight*(DN_v(9,0)*crLHS79 + DN_v(9,1)*crLHS377 + DN_v(9,2)*crLHS563 - crLHS1291*crLHS567 - crLHS1293*crLHS567 + crLHS837); + rLHS(29,7)+=gauss_weight*(DN_v(9,0)*crLHS96 + DN_v(9,1)*crLHS384 + DN_v(9,2)*crLHS568 - crLHS1291*crLHS571 - crLHS1293*crLHS571 + crLHS864); + rLHS(29,8)+=gauss_weight*(DN_v(9,0)*crLHS104 + DN_v(9,1)*crLHS392 + DN_v(9,2)*crLHS572 - crLHS1291*crLHS576 - crLHS1293*crLHS576 + crLHS1296 + crLHS890); + rLHS(29,9)+=gauss_weight*(DN_v(9,0)*crLHS111 + DN_v(9,1)*crLHS396 + DN_v(9,2)*crLHS577 - crLHS1291*crLHS581 - crLHS1293*crLHS581 + crLHS934); + rLHS(29,10)+=gauss_weight*(DN_v(9,0)*crLHS128 + DN_v(9,1)*crLHS403 + DN_v(9,2)*crLHS582 - crLHS1291*crLHS585 - crLHS1293*crLHS585 + crLHS958); + rLHS(29,11)+=gauss_weight*(DN_v(9,0)*crLHS136 + DN_v(9,1)*crLHS411 + DN_v(9,2)*crLHS586 - crLHS1291*crLHS590 - crLHS1293*crLHS590 + crLHS1297 + crLHS981); + rLHS(29,12)+=gauss_weight*(DN_v(9,0)*crLHS143 + DN_v(9,1)*crLHS415 + DN_v(9,2)*crLHS591 + crLHS1021 - crLHS1291*crLHS595 - crLHS1293*crLHS595); + rLHS(29,13)+=gauss_weight*(DN_v(9,0)*crLHS160 + DN_v(9,1)*crLHS422 + DN_v(9,2)*crLHS596 + crLHS1042 - crLHS1291*crLHS599 - crLHS1293*crLHS599); + rLHS(29,14)+=gauss_weight*(DN_v(9,0)*crLHS168 + DN_v(9,1)*crLHS430 + DN_v(9,2)*crLHS600 + crLHS1062 - crLHS1291*crLHS604 - crLHS1293*crLHS604 + crLHS1298); + rLHS(29,15)+=gauss_weight*(DN_v(9,0)*crLHS175 + DN_v(9,1)*crLHS434 + DN_v(9,2)*crLHS605 + crLHS1098 - crLHS1291*crLHS609 - crLHS1293*crLHS609); + rLHS(29,16)+=gauss_weight*(DN_v(9,0)*crLHS192 + DN_v(9,1)*crLHS441 + DN_v(9,2)*crLHS610 + crLHS1116 - crLHS1291*crLHS613 - crLHS1293*crLHS613); + rLHS(29,17)+=gauss_weight*(DN_v(9,0)*crLHS200 + DN_v(9,1)*crLHS449 + DN_v(9,2)*crLHS614 + crLHS1133 - crLHS1291*crLHS618 - crLHS1293*crLHS618 + crLHS1299); + rLHS(29,18)+=gauss_weight*(DN_v(9,0)*crLHS207 + DN_v(9,1)*crLHS453 + DN_v(9,2)*crLHS619 + crLHS1165 - crLHS1291*crLHS623 - crLHS1293*crLHS623); + rLHS(29,19)+=gauss_weight*(DN_v(9,0)*crLHS224 + DN_v(9,1)*crLHS460 + DN_v(9,2)*crLHS624 + crLHS1180 - crLHS1291*crLHS627 - crLHS1293*crLHS627); + rLHS(29,20)+=gauss_weight*(DN_v(9,0)*crLHS232 + DN_v(9,1)*crLHS468 + DN_v(9,2)*crLHS628 + crLHS1194 - crLHS1291*crLHS632 - crLHS1293*crLHS632 + crLHS1300); + rLHS(29,21)+=gauss_weight*(DN_v(9,0)*crLHS239 + DN_v(9,1)*crLHS472 + DN_v(9,2)*crLHS633 + crLHS1222 - crLHS1291*crLHS637 - crLHS1293*crLHS637); + rLHS(29,22)+=gauss_weight*(DN_v(9,0)*crLHS256 + DN_v(9,1)*crLHS479 + DN_v(9,2)*crLHS638 + crLHS1234 - crLHS1291*crLHS641 - crLHS1293*crLHS641); + rLHS(29,23)+=gauss_weight*(DN_v(9,0)*crLHS264 + DN_v(9,1)*crLHS487 + DN_v(9,2)*crLHS642 + crLHS1245 - crLHS1291*crLHS646 - crLHS1293*crLHS646 + crLHS1301); + rLHS(29,24)+=gauss_weight*(DN_v(9,0)*crLHS271 + DN_v(9,1)*crLHS491 + DN_v(9,2)*crLHS647 + crLHS1269 - crLHS1291*crLHS651 - crLHS1293*crLHS651); + rLHS(29,25)+=gauss_weight*(DN_v(9,0)*crLHS288 + DN_v(9,1)*crLHS498 + DN_v(9,2)*crLHS652 + crLHS1278 - crLHS1291*crLHS655 - crLHS1293*crLHS655); + rLHS(29,26)+=gauss_weight*(DN_v(9,0)*crLHS296 + DN_v(9,1)*crLHS506 + DN_v(9,2)*crLHS656 + crLHS1286 - crLHS1291*crLHS660 - crLHS1293*crLHS660 + crLHS1302); + rLHS(29,27)+=gauss_weight*(DN_v(9,0)*crLHS303 + DN_v(9,1)*crLHS510 + DN_v(9,2)*crLHS661 - crLHS1291*crLHS665 - crLHS1293*crLHS665 + crLHS1306); + rLHS(29,28)+=gauss_weight*(DN_v(9,0)*crLHS319 + DN_v(9,1)*crLHS517 + DN_v(9,2)*crLHS666 - crLHS1291*crLHS669 - crLHS1293*crLHS669 + crLHS1311); + rLHS(29,29)+=gauss_weight*(DN_v(9,0)*crLHS327 + DN_v(9,1)*crLHS525 + std::pow(DN_v(9,2), 2)*crLHS9 + DN_v(9,2)*crLHS670 - crLHS1291*crLHS674 - crLHS1293*crLHS674 + crLHS1303); + rLHS(29,30)+=gauss_weight*(crLHS1292*crLHS676 + crLHS1316 + crLHS309*crLHS676); + rLHS(29,31)+=gauss_weight*(crLHS1292*crLHS678 + crLHS1317 + crLHS309*crLHS678); + rLHS(29,32)+=gauss_weight*(crLHS1292*crLHS680 + crLHS1318 + crLHS309*crLHS680); + rLHS(29,33)+=gauss_weight*(crLHS1292*crLHS682 + crLHS1319 + crLHS309*crLHS682); + rLHS(30,0)+=-gauss_weight*(crLHS19*crLHS331 + crLHS330 + crLHS342*crLHS529 + crLHS539*crLHS676); + rLHS(30,1)+=-gauss_weight*(crLHS331*crLHS35 + crLHS350*crLHS529 + crLHS528 + crLHS542*crLHS676); + rLHS(30,2)+=-gauss_weight*(crLHS331*crLHS42 + crLHS356*crLHS529 + crLHS547*crLHS676 + crLHS675); + rLHS(30,3)+=-gauss_weight*(crLHS331*crLHS56 + crLHS362*crLHS529 + crLHS553*crLHS676 + crLHS731); + rLHS(30,4)+=-gauss_weight*(crLHS331*crLHS67 + crLHS370*crLHS529 + crLHS557*crLHS676 + crLHS761); + rLHS(30,5)+=-gauss_weight*(crLHS331*crLHS74 + crLHS375*crLHS529 + crLHS562*crLHS676 + crLHS790); + rLHS(30,6)+=-gauss_weight*(crLHS331*crLHS88 + crLHS381*crLHS529 + crLHS567*crLHS676 + crLHS838); + rLHS(30,7)+=-gauss_weight*(crLHS331*crLHS99 + crLHS389*crLHS529 + crLHS571*crLHS676 + crLHS865); + rLHS(30,8)+=-gauss_weight*(crLHS106*crLHS331 + crLHS394*crLHS529 + crLHS576*crLHS676 + crLHS891); + rLHS(30,9)+=-gauss_weight*(crLHS120*crLHS331 + crLHS400*crLHS529 + crLHS581*crLHS676 + crLHS935); + rLHS(30,10)+=-gauss_weight*(crLHS131*crLHS331 + crLHS408*crLHS529 + crLHS585*crLHS676 + crLHS959); + rLHS(30,11)+=-gauss_weight*(crLHS138*crLHS331 + crLHS413*crLHS529 + crLHS590*crLHS676 + crLHS982); + rLHS(30,12)+=-gauss_weight*(crLHS1022 + crLHS152*crLHS331 + crLHS419*crLHS529 + crLHS595*crLHS676); + rLHS(30,13)+=-gauss_weight*(crLHS1043 + crLHS163*crLHS331 + crLHS427*crLHS529 + crLHS599*crLHS676); + rLHS(30,14)+=-gauss_weight*(crLHS1063 + crLHS170*crLHS331 + crLHS432*crLHS529 + crLHS604*crLHS676); + rLHS(30,15)+=-gauss_weight*(crLHS1099 + crLHS184*crLHS331 + crLHS438*crLHS529 + crLHS609*crLHS676); + rLHS(30,16)+=-gauss_weight*(crLHS1117 + crLHS195*crLHS331 + crLHS446*crLHS529 + crLHS613*crLHS676); + rLHS(30,17)+=-gauss_weight*(crLHS1134 + crLHS202*crLHS331 + crLHS451*crLHS529 + crLHS618*crLHS676); + rLHS(30,18)+=-gauss_weight*(crLHS1166 + crLHS216*crLHS331 + crLHS457*crLHS529 + crLHS623*crLHS676); + rLHS(30,19)+=-gauss_weight*(crLHS1181 + crLHS227*crLHS331 + crLHS465*crLHS529 + crLHS627*crLHS676); + rLHS(30,20)+=-gauss_weight*(crLHS1195 + crLHS234*crLHS331 + crLHS470*crLHS529 + crLHS632*crLHS676); + rLHS(30,21)+=-gauss_weight*(crLHS1223 + crLHS248*crLHS331 + crLHS476*crLHS529 + crLHS637*crLHS676); + rLHS(30,22)+=-gauss_weight*(crLHS1235 + crLHS259*crLHS331 + crLHS484*crLHS529 + crLHS641*crLHS676); + rLHS(30,23)+=-gauss_weight*(crLHS1246 + crLHS266*crLHS331 + crLHS489*crLHS529 + crLHS646*crLHS676); + rLHS(30,24)+=-gauss_weight*(crLHS1270 + crLHS280*crLHS331 + crLHS495*crLHS529 + crLHS651*crLHS676); + rLHS(30,25)+=-gauss_weight*(crLHS1279 + crLHS291*crLHS331 + crLHS503*crLHS529 + crLHS655*crLHS676); + rLHS(30,26)+=-gauss_weight*(crLHS1287 + crLHS298*crLHS331 + crLHS508*crLHS529 + crLHS660*crLHS676); + rLHS(30,27)+=-gauss_weight*(crLHS1307 + crLHS311*crLHS331 + crLHS514*crLHS529 + crLHS665*crLHS676); + rLHS(30,28)+=-gauss_weight*(crLHS1312 + crLHS322*crLHS331 + crLHS522*crLHS529 + crLHS669*crLHS676); + rLHS(30,29)+=-gauss_weight*(crLHS1316 + crLHS329*crLHS331 + crLHS527*crLHS529 + crLHS674*crLHS676); + rLHS(30,30)+=crLHS1320*(std::pow(DN_p(0,0), 2) + std::pow(DN_p(0,1), 2) + std::pow(DN_p(0,2), 2)); + rLHS(30,31)+=crLHS1321; + rLHS(30,32)+=crLHS1322; + rLHS(30,33)+=crLHS1323; + rLHS(31,0)+=-gauss_weight*(crLHS19*crLHS333 + crLHS332 + crLHS342*crLHS531 + crLHS539*crLHS678); + rLHS(31,1)+=-gauss_weight*(crLHS333*crLHS35 + crLHS350*crLHS531 + crLHS530 + crLHS542*crLHS678); + rLHS(31,2)+=-gauss_weight*(crLHS333*crLHS42 + crLHS356*crLHS531 + crLHS547*crLHS678 + crLHS677); + rLHS(31,3)+=-gauss_weight*(crLHS333*crLHS56 + crLHS362*crLHS531 + crLHS553*crLHS678 + crLHS732); + rLHS(31,4)+=-gauss_weight*(crLHS333*crLHS67 + crLHS370*crLHS531 + crLHS557*crLHS678 + crLHS762); + rLHS(31,5)+=-gauss_weight*(crLHS333*crLHS74 + crLHS375*crLHS531 + crLHS562*crLHS678 + crLHS791); + rLHS(31,6)+=-gauss_weight*(crLHS333*crLHS88 + crLHS381*crLHS531 + crLHS567*crLHS678 + crLHS839); + rLHS(31,7)+=-gauss_weight*(crLHS333*crLHS99 + crLHS389*crLHS531 + crLHS571*crLHS678 + crLHS866); + rLHS(31,8)+=-gauss_weight*(crLHS106*crLHS333 + crLHS394*crLHS531 + crLHS576*crLHS678 + crLHS892); + rLHS(31,9)+=-gauss_weight*(crLHS120*crLHS333 + crLHS400*crLHS531 + crLHS581*crLHS678 + crLHS936); + rLHS(31,10)+=-gauss_weight*(crLHS131*crLHS333 + crLHS408*crLHS531 + crLHS585*crLHS678 + crLHS960); + rLHS(31,11)+=-gauss_weight*(crLHS138*crLHS333 + crLHS413*crLHS531 + crLHS590*crLHS678 + crLHS983); + rLHS(31,12)+=-gauss_weight*(crLHS1023 + crLHS152*crLHS333 + crLHS419*crLHS531 + crLHS595*crLHS678); + rLHS(31,13)+=-gauss_weight*(crLHS1044 + crLHS163*crLHS333 + crLHS427*crLHS531 + crLHS599*crLHS678); + rLHS(31,14)+=-gauss_weight*(crLHS1064 + crLHS170*crLHS333 + crLHS432*crLHS531 + crLHS604*crLHS678); + rLHS(31,15)+=-gauss_weight*(crLHS1100 + crLHS184*crLHS333 + crLHS438*crLHS531 + crLHS609*crLHS678); + rLHS(31,16)+=-gauss_weight*(crLHS1118 + crLHS195*crLHS333 + crLHS446*crLHS531 + crLHS613*crLHS678); + rLHS(31,17)+=-gauss_weight*(crLHS1135 + crLHS202*crLHS333 + crLHS451*crLHS531 + crLHS618*crLHS678); + rLHS(31,18)+=-gauss_weight*(crLHS1167 + crLHS216*crLHS333 + crLHS457*crLHS531 + crLHS623*crLHS678); + rLHS(31,19)+=-gauss_weight*(crLHS1182 + crLHS227*crLHS333 + crLHS465*crLHS531 + crLHS627*crLHS678); + rLHS(31,20)+=-gauss_weight*(crLHS1196 + crLHS234*crLHS333 + crLHS470*crLHS531 + crLHS632*crLHS678); + rLHS(31,21)+=-gauss_weight*(crLHS1224 + crLHS248*crLHS333 + crLHS476*crLHS531 + crLHS637*crLHS678); + rLHS(31,22)+=-gauss_weight*(crLHS1236 + crLHS259*crLHS333 + crLHS484*crLHS531 + crLHS641*crLHS678); + rLHS(31,23)+=-gauss_weight*(crLHS1247 + crLHS266*crLHS333 + crLHS489*crLHS531 + crLHS646*crLHS678); + rLHS(31,24)+=-gauss_weight*(crLHS1271 + crLHS280*crLHS333 + crLHS495*crLHS531 + crLHS651*crLHS678); + rLHS(31,25)+=-gauss_weight*(crLHS1280 + crLHS291*crLHS333 + crLHS503*crLHS531 + crLHS655*crLHS678); + rLHS(31,26)+=-gauss_weight*(crLHS1288 + crLHS298*crLHS333 + crLHS508*crLHS531 + crLHS660*crLHS678); + rLHS(31,27)+=-gauss_weight*(crLHS1308 + crLHS311*crLHS333 + crLHS514*crLHS531 + crLHS665*crLHS678); + rLHS(31,28)+=-gauss_weight*(crLHS1313 + crLHS322*crLHS333 + crLHS522*crLHS531 + crLHS669*crLHS678); + rLHS(31,29)+=-gauss_weight*(crLHS1317 + crLHS329*crLHS333 + crLHS527*crLHS531 + crLHS674*crLHS678); + rLHS(31,30)+=crLHS1321; + rLHS(31,31)+=crLHS1320*(std::pow(DN_p(1,0), 2) + std::pow(DN_p(1,1), 2) + std::pow(DN_p(1,2), 2)); + rLHS(31,32)+=crLHS1324; + rLHS(31,33)+=crLHS1325; + rLHS(32,0)+=-gauss_weight*(crLHS19*crLHS335 + crLHS334 + crLHS342*crLHS533 + crLHS539*crLHS680); + rLHS(32,1)+=-gauss_weight*(crLHS335*crLHS35 + crLHS350*crLHS533 + crLHS532 + crLHS542*crLHS680); + rLHS(32,2)+=-gauss_weight*(crLHS335*crLHS42 + crLHS356*crLHS533 + crLHS547*crLHS680 + crLHS679); + rLHS(32,3)+=-gauss_weight*(crLHS335*crLHS56 + crLHS362*crLHS533 + crLHS553*crLHS680 + crLHS733); + rLHS(32,4)+=-gauss_weight*(crLHS335*crLHS67 + crLHS370*crLHS533 + crLHS557*crLHS680 + crLHS763); + rLHS(32,5)+=-gauss_weight*(crLHS335*crLHS74 + crLHS375*crLHS533 + crLHS562*crLHS680 + crLHS792); + rLHS(32,6)+=-gauss_weight*(crLHS335*crLHS88 + crLHS381*crLHS533 + crLHS567*crLHS680 + crLHS840); + rLHS(32,7)+=-gauss_weight*(crLHS335*crLHS99 + crLHS389*crLHS533 + crLHS571*crLHS680 + crLHS867); + rLHS(32,8)+=-gauss_weight*(crLHS106*crLHS335 + crLHS394*crLHS533 + crLHS576*crLHS680 + crLHS893); + rLHS(32,9)+=-gauss_weight*(crLHS120*crLHS335 + crLHS400*crLHS533 + crLHS581*crLHS680 + crLHS937); + rLHS(32,10)+=-gauss_weight*(crLHS131*crLHS335 + crLHS408*crLHS533 + crLHS585*crLHS680 + crLHS961); + rLHS(32,11)+=-gauss_weight*(crLHS138*crLHS335 + crLHS413*crLHS533 + crLHS590*crLHS680 + crLHS984); + rLHS(32,12)+=-gauss_weight*(crLHS1024 + crLHS152*crLHS335 + crLHS419*crLHS533 + crLHS595*crLHS680); + rLHS(32,13)+=-gauss_weight*(crLHS1045 + crLHS163*crLHS335 + crLHS427*crLHS533 + crLHS599*crLHS680); + rLHS(32,14)+=-gauss_weight*(crLHS1065 + crLHS170*crLHS335 + crLHS432*crLHS533 + crLHS604*crLHS680); + rLHS(32,15)+=-gauss_weight*(crLHS1101 + crLHS184*crLHS335 + crLHS438*crLHS533 + crLHS609*crLHS680); + rLHS(32,16)+=-gauss_weight*(crLHS1119 + crLHS195*crLHS335 + crLHS446*crLHS533 + crLHS613*crLHS680); + rLHS(32,17)+=-gauss_weight*(crLHS1136 + crLHS202*crLHS335 + crLHS451*crLHS533 + crLHS618*crLHS680); + rLHS(32,18)+=-gauss_weight*(crLHS1168 + crLHS216*crLHS335 + crLHS457*crLHS533 + crLHS623*crLHS680); + rLHS(32,19)+=-gauss_weight*(crLHS1183 + crLHS227*crLHS335 + crLHS465*crLHS533 + crLHS627*crLHS680); + rLHS(32,20)+=-gauss_weight*(crLHS1197 + crLHS234*crLHS335 + crLHS470*crLHS533 + crLHS632*crLHS680); + rLHS(32,21)+=-gauss_weight*(crLHS1225 + crLHS248*crLHS335 + crLHS476*crLHS533 + crLHS637*crLHS680); + rLHS(32,22)+=-gauss_weight*(crLHS1237 + crLHS259*crLHS335 + crLHS484*crLHS533 + crLHS641*crLHS680); + rLHS(32,23)+=-gauss_weight*(crLHS1248 + crLHS266*crLHS335 + crLHS489*crLHS533 + crLHS646*crLHS680); + rLHS(32,24)+=-gauss_weight*(crLHS1272 + crLHS280*crLHS335 + crLHS495*crLHS533 + crLHS651*crLHS680); + rLHS(32,25)+=-gauss_weight*(crLHS1281 + crLHS291*crLHS335 + crLHS503*crLHS533 + crLHS655*crLHS680); + rLHS(32,26)+=-gauss_weight*(crLHS1289 + crLHS298*crLHS335 + crLHS508*crLHS533 + crLHS660*crLHS680); + rLHS(32,27)+=-gauss_weight*(crLHS1309 + crLHS311*crLHS335 + crLHS514*crLHS533 + crLHS665*crLHS680); + rLHS(32,28)+=-gauss_weight*(crLHS1314 + crLHS322*crLHS335 + crLHS522*crLHS533 + crLHS669*crLHS680); + rLHS(32,29)+=-gauss_weight*(crLHS1318 + crLHS329*crLHS335 + crLHS527*crLHS533 + crLHS674*crLHS680); + rLHS(32,30)+=crLHS1322; + rLHS(32,31)+=crLHS1324; + rLHS(32,32)+=crLHS1320*(std::pow(DN_p(2,0), 2) + std::pow(DN_p(2,1), 2) + std::pow(DN_p(2,2), 2)); + rLHS(32,33)+=crLHS1326; + rLHS(33,0)+=-gauss_weight*(crLHS19*crLHS337 + crLHS336 + crLHS342*crLHS535 + crLHS539*crLHS682); + rLHS(33,1)+=-gauss_weight*(crLHS337*crLHS35 + crLHS350*crLHS535 + crLHS534 + crLHS542*crLHS682); + rLHS(33,2)+=-gauss_weight*(crLHS337*crLHS42 + crLHS356*crLHS535 + crLHS547*crLHS682 + crLHS681); + rLHS(33,3)+=-gauss_weight*(crLHS337*crLHS56 + crLHS362*crLHS535 + crLHS553*crLHS682 + crLHS734); + rLHS(33,4)+=-gauss_weight*(crLHS337*crLHS67 + crLHS370*crLHS535 + crLHS557*crLHS682 + crLHS764); + rLHS(33,5)+=-gauss_weight*(crLHS337*crLHS74 + crLHS375*crLHS535 + crLHS562*crLHS682 + crLHS793); + rLHS(33,6)+=-gauss_weight*(crLHS337*crLHS88 + crLHS381*crLHS535 + crLHS567*crLHS682 + crLHS841); + rLHS(33,7)+=-gauss_weight*(crLHS337*crLHS99 + crLHS389*crLHS535 + crLHS571*crLHS682 + crLHS868); + rLHS(33,8)+=-gauss_weight*(crLHS106*crLHS337 + crLHS394*crLHS535 + crLHS576*crLHS682 + crLHS894); + rLHS(33,9)+=-gauss_weight*(crLHS120*crLHS337 + crLHS400*crLHS535 + crLHS581*crLHS682 + crLHS938); + rLHS(33,10)+=-gauss_weight*(crLHS131*crLHS337 + crLHS408*crLHS535 + crLHS585*crLHS682 + crLHS962); + rLHS(33,11)+=-gauss_weight*(crLHS138*crLHS337 + crLHS413*crLHS535 + crLHS590*crLHS682 + crLHS985); + rLHS(33,12)+=-gauss_weight*(crLHS1025 + crLHS152*crLHS337 + crLHS419*crLHS535 + crLHS595*crLHS682); + rLHS(33,13)+=-gauss_weight*(crLHS1046 + crLHS163*crLHS337 + crLHS427*crLHS535 + crLHS599*crLHS682); + rLHS(33,14)+=-gauss_weight*(crLHS1066 + crLHS170*crLHS337 + crLHS432*crLHS535 + crLHS604*crLHS682); + rLHS(33,15)+=-gauss_weight*(crLHS1102 + crLHS184*crLHS337 + crLHS438*crLHS535 + crLHS609*crLHS682); + rLHS(33,16)+=-gauss_weight*(crLHS1120 + crLHS195*crLHS337 + crLHS446*crLHS535 + crLHS613*crLHS682); + rLHS(33,17)+=-gauss_weight*(crLHS1137 + crLHS202*crLHS337 + crLHS451*crLHS535 + crLHS618*crLHS682); + rLHS(33,18)+=-gauss_weight*(crLHS1169 + crLHS216*crLHS337 + crLHS457*crLHS535 + crLHS623*crLHS682); + rLHS(33,19)+=-gauss_weight*(crLHS1184 + crLHS227*crLHS337 + crLHS465*crLHS535 + crLHS627*crLHS682); + rLHS(33,20)+=-gauss_weight*(crLHS1198 + crLHS234*crLHS337 + crLHS470*crLHS535 + crLHS632*crLHS682); + rLHS(33,21)+=-gauss_weight*(crLHS1226 + crLHS248*crLHS337 + crLHS476*crLHS535 + crLHS637*crLHS682); + rLHS(33,22)+=-gauss_weight*(crLHS1238 + crLHS259*crLHS337 + crLHS484*crLHS535 + crLHS641*crLHS682); + rLHS(33,23)+=-gauss_weight*(crLHS1249 + crLHS266*crLHS337 + crLHS489*crLHS535 + crLHS646*crLHS682); + rLHS(33,24)+=-gauss_weight*(crLHS1273 + crLHS280*crLHS337 + crLHS495*crLHS535 + crLHS651*crLHS682); + rLHS(33,25)+=-gauss_weight*(crLHS1282 + crLHS291*crLHS337 + crLHS503*crLHS535 + crLHS655*crLHS682); + rLHS(33,26)+=-gauss_weight*(crLHS1290 + crLHS298*crLHS337 + crLHS508*crLHS535 + crLHS660*crLHS682); + rLHS(33,27)+=-gauss_weight*(crLHS1310 + crLHS311*crLHS337 + crLHS514*crLHS535 + crLHS665*crLHS682); + rLHS(33,28)+=-gauss_weight*(crLHS1315 + crLHS322*crLHS337 + crLHS522*crLHS535 + crLHS669*crLHS682); + rLHS(33,29)+=-gauss_weight*(crLHS1319 + crLHS329*crLHS337 + crLHS527*crLHS535 + crLHS674*crLHS682); + rLHS(33,30)+=crLHS1323; + rLHS(33,31)+=crLHS1325; + rLHS(33,32)+=crLHS1326; + rLHS(33,33)+=crLHS1320*(std::pow(DN_p(3,0), 2) + std::pow(DN_p(3,1), 2) + std::pow(DN_p(3,2), 2)); + +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<2>::AddGaussPointRightHandSideContribution( + const ElementDataContainer& rData, + VectorType& rRHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Get nodal data + const auto& r_v = rData.Velocity; + const auto& r_vn = rData.VelocityOld1; + const auto& r_vnn = rData.VelocityOld2; + const auto& r_vmesh = rData.MeshVelocity; + const auto& r_f = rData.BodyForce; + const auto& r_p = rData.Pressure; + + // Calculate convective velocity + const BoundedMatrix vconv = r_v - r_vmesh; + + // Get stress from material response + const auto& r_stress = rData.ShearStress; + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble RHS contribution + const double gauss_weight = rData.Weight; + const double crRHS0 = N_p[0]*r_p[0] + N_p[1]*r_p[1] + N_p[2]*r_p[2]; + const double crRHS1 = rho*(N_v[0]*r_f(0,0) + N_v[1]*r_f(1,0) + N_v[2]*r_f(2,0) + N_v[3]*r_f(3,0) + N_v[4]*r_f(4,0) + N_v[5]*r_f(5,0)); + const double crRHS2 = rho*(N_v[0]*(rData.BDF0*r_v(0,0) + rData.BDF1*r_vn(0,0) + rData.BDF2*r_vnn(0,0)) + N_v[1]*(rData.BDF0*r_v(1,0) + rData.BDF1*r_vn(1,0) + rData.BDF2*r_vnn(1,0)) + N_v[2]*(rData.BDF0*r_v(2,0) + rData.BDF1*r_vn(2,0) + rData.BDF2*r_vnn(2,0)) + N_v[3]*(rData.BDF0*r_v(3,0) + rData.BDF1*r_vn(3,0) + rData.BDF2*r_vnn(3,0)) + N_v[4]*(rData.BDF0*r_v(4,0) + rData.BDF1*r_vn(4,0) + rData.BDF2*r_vnn(4,0)) + N_v[5]*(rData.BDF0*r_v(5,0) + rData.BDF1*r_vn(5,0) + rData.BDF2*r_vnn(5,0))); + const double crRHS3 = DN_v(0,0)*r_v(0,0) + DN_v(1,0)*r_v(1,0) + DN_v(2,0)*r_v(2,0) + DN_v(3,0)*r_v(3,0) + DN_v(4,0)*r_v(4,0) + DN_v(5,0)*r_v(5,0); + const double crRHS4 = N_v[0]*vconv(0,0) + N_v[1]*vconv(1,0) + N_v[2]*vconv(2,0) + N_v[3]*vconv(3,0) + N_v[4]*vconv(4,0) + N_v[5]*vconv(5,0); + const double crRHS5 = N_v[0]*vconv(0,1) + N_v[1]*vconv(1,1) + N_v[2]*vconv(2,1) + N_v[3]*vconv(3,1) + N_v[4]*vconv(4,1) + N_v[5]*vconv(5,1); + const double crRHS6 = rho*(crRHS3*crRHS4 + crRHS5*(DN_v(0,1)*r_v(0,0) + DN_v(1,1)*r_v(1,0) + DN_v(2,1)*r_v(2,0) + DN_v(3,1)*r_v(3,0) + DN_v(4,1)*r_v(4,0) + DN_v(5,1)*r_v(5,0))); + const double crRHS7 = DN_v(0,1)*r_v(0,1) + DN_v(1,1)*r_v(1,1) + DN_v(2,1)*r_v(2,1) + DN_v(3,1)*r_v(3,1) + DN_v(4,1)*r_v(4,1) + DN_v(5,1)*r_v(5,1); + const double crRHS8 = crRHS3 + crRHS7; + const double crRHS9 = rho*stab_c2*std::sqrt(std::pow(crRHS4, 2) + std::pow(crRHS5, 2)); + const double crRHS10 = crRHS8*(crRHS9*h/stab_c1 + mu); + const double crRHS11 = 1.0*C(0,0); + const double crRHS12 = DDN_v[0](0,0)*r_v(0,0); + const double crRHS13 = DDN_v[1](0,0)*r_v(1,0); + const double crRHS14 = DDN_v[2](0,0)*r_v(2,0); + const double crRHS15 = DDN_v[3](0,0)*r_v(3,0); + const double crRHS16 = DDN_v[4](0,0)*r_v(4,0); + const double crRHS17 = DDN_v[5](0,0)*r_v(5,0); + const double crRHS18 = 1.0*C(0,1); + const double crRHS19 = DDN_v[0](0,1)*r_v(0,1); + const double crRHS20 = DDN_v[1](0,1)*r_v(1,1); + const double crRHS21 = DDN_v[2](0,1)*r_v(2,1); + const double crRHS22 = DDN_v[3](0,1)*r_v(3,1); + const double crRHS23 = DDN_v[4](0,1)*r_v(4,1); + const double crRHS24 = DDN_v[5](0,1)*r_v(5,1); + const double crRHS25 = 1.0*C(0,2); + const double crRHS26 = 1.0*C(1,2); + const double crRHS27 = DDN_v[0](0,0)*r_v(0,1) + DDN_v[0](0,1)*r_v(0,0); + const double crRHS28 = DDN_v[1](0,0)*r_v(1,1) + DDN_v[1](0,1)*r_v(1,0); + const double crRHS29 = DDN_v[2](0,0)*r_v(2,1) + DDN_v[2](0,1)*r_v(2,0); + const double crRHS30 = DDN_v[3](0,0)*r_v(3,1) + DDN_v[3](0,1)*r_v(3,0); + const double crRHS31 = DDN_v[4](0,0)*r_v(4,1) + DDN_v[4](0,1)*r_v(4,0); + const double crRHS32 = DDN_v[5](0,0)*r_v(5,1) + DDN_v[5](0,1)*r_v(5,0); + const double crRHS33 = 1.0*C(2,2); + const double crRHS34 = 1.0/(crRHS9/h + dyn_tau*rho/rData.DeltaTime + mu*stab_c1/std::pow(h, 2)); + const double crRHS35 = crRHS34*(-DN_p(0,0)*r_p[0] - DN_p(1,0)*r_p[1] - DN_p(2,0)*r_p[2] + crRHS1 + crRHS11*crRHS12 + crRHS11*crRHS13 + crRHS11*crRHS14 + crRHS11*crRHS15 + crRHS11*crRHS16 + crRHS11*crRHS17 + crRHS12*crRHS25 + crRHS13*crRHS25 + crRHS14*crRHS25 + crRHS15*crRHS25 + crRHS16*crRHS25 + crRHS17*crRHS25 + crRHS18*crRHS19 + crRHS18*crRHS20 + crRHS18*crRHS21 + crRHS18*crRHS22 + crRHS18*crRHS23 + crRHS18*crRHS24 + crRHS19*crRHS26 - crRHS2 + crRHS20*crRHS26 + crRHS21*crRHS26 + crRHS22*crRHS26 + crRHS23*crRHS26 + crRHS24*crRHS26 + crRHS25*crRHS27 + crRHS25*crRHS28 + crRHS25*crRHS29 + crRHS25*crRHS30 + crRHS25*crRHS31 + crRHS25*crRHS32 + crRHS27*crRHS33 + crRHS28*crRHS33 + crRHS29*crRHS33 + crRHS30*crRHS33 + crRHS31*crRHS33 + crRHS32*crRHS33 - crRHS6); + const double crRHS36 = rho*(DN_v(0,0)*vconv(0,0) + DN_v(0,1)*vconv(0,1) + DN_v(1,0)*vconv(1,0) + DN_v(1,1)*vconv(1,1) + DN_v(2,0)*vconv(2,0) + DN_v(2,1)*vconv(2,1) + DN_v(3,0)*vconv(3,0) + DN_v(3,1)*vconv(3,1) + DN_v(4,0)*vconv(4,0) + DN_v(4,1)*vconv(4,1) + DN_v(5,0)*vconv(5,0) + DN_v(5,1)*vconv(5,1)); + const double crRHS37 = N_v[0]*crRHS36; + const double crRHS38 = rho*(DN_v(0,0)*crRHS4 + DN_v(0,1)*crRHS5); + const double crRHS39 = rho*(N_v[0]*r_f(0,1) + N_v[1]*r_f(1,1) + N_v[2]*r_f(2,1) + N_v[3]*r_f(3,1) + N_v[4]*r_f(4,1) + N_v[5]*r_f(5,1)); + const double crRHS40 = rho*(N_v[0]*(rData.BDF0*r_v(0,1) + rData.BDF1*r_vn(0,1) + rData.BDF2*r_vnn(0,1)) + N_v[1]*(rData.BDF0*r_v(1,1) + rData.BDF1*r_vn(1,1) + rData.BDF2*r_vnn(1,1)) + N_v[2]*(rData.BDF0*r_v(2,1) + rData.BDF1*r_vn(2,1) + rData.BDF2*r_vnn(2,1)) + N_v[3]*(rData.BDF0*r_v(3,1) + rData.BDF1*r_vn(3,1) + rData.BDF2*r_vnn(3,1)) + N_v[4]*(rData.BDF0*r_v(4,1) + rData.BDF1*r_vn(4,1) + rData.BDF2*r_vnn(4,1)) + N_v[5]*(rData.BDF0*r_v(5,1) + rData.BDF1*r_vn(5,1) + rData.BDF2*r_vnn(5,1))); + const double crRHS41 = rho*(crRHS4*(DN_v(0,0)*r_v(0,1) + DN_v(1,0)*r_v(1,1) + DN_v(2,0)*r_v(2,1) + DN_v(3,0)*r_v(3,1) + DN_v(4,0)*r_v(4,1) + DN_v(5,0)*r_v(5,1)) + crRHS5*crRHS7); + const double crRHS42 = DDN_v[0](1,0)*r_v(0,0); + const double crRHS43 = DDN_v[1](1,0)*r_v(1,0); + const double crRHS44 = DDN_v[2](1,0)*r_v(2,0); + const double crRHS45 = DDN_v[3](1,0)*r_v(3,0); + const double crRHS46 = DDN_v[4](1,0)*r_v(4,0); + const double crRHS47 = DDN_v[5](1,0)*r_v(5,0); + const double crRHS48 = 1.0*C(1,1); + const double crRHS49 = DDN_v[0](1,1)*r_v(0,1); + const double crRHS50 = DDN_v[1](1,1)*r_v(1,1); + const double crRHS51 = DDN_v[2](1,1)*r_v(2,1); + const double crRHS52 = DDN_v[3](1,1)*r_v(3,1); + const double crRHS53 = DDN_v[4](1,1)*r_v(4,1); + const double crRHS54 = DDN_v[5](1,1)*r_v(5,1); + const double crRHS55 = DDN_v[0](1,0)*r_v(0,1) + DDN_v[0](1,1)*r_v(0,0); + const double crRHS56 = DDN_v[1](1,0)*r_v(1,1) + DDN_v[1](1,1)*r_v(1,0); + const double crRHS57 = DDN_v[2](1,0)*r_v(2,1) + DDN_v[2](1,1)*r_v(2,0); + const double crRHS58 = DDN_v[3](1,0)*r_v(3,1) + DDN_v[3](1,1)*r_v(3,0); + const double crRHS59 = DDN_v[4](1,0)*r_v(4,1) + DDN_v[4](1,1)*r_v(4,0); + const double crRHS60 = DDN_v[5](1,0)*r_v(5,1) + DDN_v[5](1,1)*r_v(5,0); + const double crRHS61 = crRHS34*(-DN_p(0,1)*r_p[0] - DN_p(1,1)*r_p[1] - DN_p(2,1)*r_p[2] + crRHS18*crRHS42 + crRHS18*crRHS43 + crRHS18*crRHS44 + crRHS18*crRHS45 + crRHS18*crRHS46 + crRHS18*crRHS47 + crRHS25*crRHS42 + crRHS25*crRHS43 + crRHS25*crRHS44 + crRHS25*crRHS45 + crRHS25*crRHS46 + crRHS25*crRHS47 + crRHS26*crRHS49 + crRHS26*crRHS50 + crRHS26*crRHS51 + crRHS26*crRHS52 + crRHS26*crRHS53 + crRHS26*crRHS54 + crRHS26*crRHS55 + crRHS26*crRHS56 + crRHS26*crRHS57 + crRHS26*crRHS58 + crRHS26*crRHS59 + crRHS26*crRHS60 + crRHS33*crRHS55 + crRHS33*crRHS56 + crRHS33*crRHS57 + crRHS33*crRHS58 + crRHS33*crRHS59 + crRHS33*crRHS60 + crRHS39 - crRHS40 - crRHS41 + crRHS48*crRHS49 + crRHS48*crRHS50 + crRHS48*crRHS51 + crRHS48*crRHS52 + crRHS48*crRHS53 + crRHS48*crRHS54); + const double crRHS62 = N_v[1]*crRHS36; + const double crRHS63 = rho*(DN_v(1,0)*crRHS4 + DN_v(1,1)*crRHS5); + const double crRHS64 = N_v[2]*crRHS36; + const double crRHS65 = rho*(DN_v(2,0)*crRHS4 + DN_v(2,1)*crRHS5); + const double crRHS66 = N_v[3]*crRHS36; + const double crRHS67 = rho*(DN_v(3,0)*crRHS4 + DN_v(3,1)*crRHS5); + const double crRHS68 = N_v[4]*crRHS36; + const double crRHS69 = rho*(DN_v(4,0)*crRHS4 + DN_v(4,1)*crRHS5); + const double crRHS70 = N_v[5]*crRHS36; + const double crRHS71 = rho*(DN_v(5,0)*crRHS4 + DN_v(5,1)*crRHS5); + rRHS[0]+=-gauss_weight*(-DN_v(0,0)*crRHS0 + DN_v(0,0)*crRHS10 + DN_v(0,0)*r_stress[0] + DN_v(0,1)*r_stress[2] - N_v[0]*crRHS1 + N_v[0]*crRHS2 + N_v[0]*crRHS6 - crRHS35*crRHS37 - crRHS35*crRHS38); + rRHS[1]+=-gauss_weight*(DN_v(0,0)*r_stress[2] - DN_v(0,1)*crRHS0 + DN_v(0,1)*crRHS10 + DN_v(0,1)*r_stress[1] - N_v[0]*crRHS39 + N_v[0]*crRHS40 + N_v[0]*crRHS41 - crRHS37*crRHS61 - crRHS38*crRHS61); + rRHS[2]+=-gauss_weight*(-DN_v(1,0)*crRHS0 + DN_v(1,0)*crRHS10 + DN_v(1,0)*r_stress[0] + DN_v(1,1)*r_stress[2] - N_v[1]*crRHS1 + N_v[1]*crRHS2 + N_v[1]*crRHS6 - crRHS35*crRHS62 - crRHS35*crRHS63); + rRHS[3]+=-gauss_weight*(DN_v(1,0)*r_stress[2] - DN_v(1,1)*crRHS0 + DN_v(1,1)*crRHS10 + DN_v(1,1)*r_stress[1] - N_v[1]*crRHS39 + N_v[1]*crRHS40 + N_v[1]*crRHS41 - crRHS61*crRHS62 - crRHS61*crRHS63); + rRHS[4]+=-gauss_weight*(-DN_v(2,0)*crRHS0 + DN_v(2,0)*crRHS10 + DN_v(2,0)*r_stress[0] + DN_v(2,1)*r_stress[2] - N_v[2]*crRHS1 + N_v[2]*crRHS2 + N_v[2]*crRHS6 - crRHS35*crRHS64 - crRHS35*crRHS65); + rRHS[5]+=-gauss_weight*(DN_v(2,0)*r_stress[2] - DN_v(2,1)*crRHS0 + DN_v(2,1)*crRHS10 + DN_v(2,1)*r_stress[1] - N_v[2]*crRHS39 + N_v[2]*crRHS40 + N_v[2]*crRHS41 - crRHS61*crRHS64 - crRHS61*crRHS65); + rRHS[6]+=-gauss_weight*(-DN_v(3,0)*crRHS0 + DN_v(3,0)*crRHS10 + DN_v(3,0)*r_stress[0] + DN_v(3,1)*r_stress[2] - N_v[3]*crRHS1 + N_v[3]*crRHS2 + N_v[3]*crRHS6 - crRHS35*crRHS66 - crRHS35*crRHS67); + rRHS[7]+=-gauss_weight*(DN_v(3,0)*r_stress[2] - DN_v(3,1)*crRHS0 + DN_v(3,1)*crRHS10 + DN_v(3,1)*r_stress[1] - N_v[3]*crRHS39 + N_v[3]*crRHS40 + N_v[3]*crRHS41 - crRHS61*crRHS66 - crRHS61*crRHS67); + rRHS[8]+=-gauss_weight*(-DN_v(4,0)*crRHS0 + DN_v(4,0)*crRHS10 + DN_v(4,0)*r_stress[0] + DN_v(4,1)*r_stress[2] - N_v[4]*crRHS1 + N_v[4]*crRHS2 + N_v[4]*crRHS6 - crRHS35*crRHS68 - crRHS35*crRHS69); + rRHS[9]+=-gauss_weight*(DN_v(4,0)*r_stress[2] - DN_v(4,1)*crRHS0 + DN_v(4,1)*crRHS10 + DN_v(4,1)*r_stress[1] - N_v[4]*crRHS39 + N_v[4]*crRHS40 + N_v[4]*crRHS41 - crRHS61*crRHS68 - crRHS61*crRHS69); + rRHS[10]+=-gauss_weight*(-DN_v(5,0)*crRHS0 + DN_v(5,0)*crRHS10 + DN_v(5,0)*r_stress[0] + DN_v(5,1)*r_stress[2] - N_v[5]*crRHS1 + N_v[5]*crRHS2 + N_v[5]*crRHS6 - crRHS35*crRHS70 - crRHS35*crRHS71); + rRHS[11]+=-gauss_weight*(DN_v(5,0)*r_stress[2] - DN_v(5,1)*crRHS0 + DN_v(5,1)*crRHS10 + DN_v(5,1)*r_stress[1] - N_v[5]*crRHS39 + N_v[5]*crRHS40 + N_v[5]*crRHS41 - crRHS61*crRHS70 - crRHS61*crRHS71); + rRHS[12]+=gauss_weight*(DN_p(0,0)*crRHS35 + DN_p(0,1)*crRHS61 - N_p[0]*crRHS8); + rRHS[13]+=gauss_weight*(DN_p(1,0)*crRHS35 + DN_p(1,1)*crRHS61 - N_p[1]*crRHS8); + rRHS[14]+=gauss_weight*(DN_p(2,0)*crRHS35 + DN_p(2,1)*crRHS61 - N_p[2]*crRHS8); + +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<3>::AddGaussPointRightHandSideContribution( + const ElementDataContainer& rData, + VectorType& rRHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Get nodal data + const auto& r_v = rData.Velocity; + const auto& r_vn = rData.VelocityOld1; + const auto& r_vnn = rData.VelocityOld2; + const auto& r_vmesh = rData.MeshVelocity; + const auto& r_f = rData.BodyForce; + const auto& r_p = rData.Pressure; + + // Calculate convective velocity + const BoundedMatrix vconv = r_v - r_vmesh; + + // Get stress from material response + const auto& r_stress = rData.ShearStress; + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble RHS contribution + const double gauss_weight = rData.Weight; + const double crRHS0 = N_p[0]*r_p[0] + N_p[1]*r_p[1] + N_p[2]*r_p[2] + N_p[3]*r_p[3]; + const double crRHS1 = rho*(N_v[0]*r_f(0,0) + N_v[1]*r_f(1,0) + N_v[2]*r_f(2,0) + N_v[3]*r_f(3,0) + N_v[4]*r_f(4,0) + N_v[5]*r_f(5,0) + N_v[6]*r_f(6,0) + N_v[7]*r_f(7,0) + N_v[8]*r_f(8,0) + N_v[9]*r_f(9,0)); + const double crRHS2 = rho*(N_v[0]*(rData.BDF0*r_v(0,0) + rData.BDF1*r_vn(0,0) + rData.BDF2*r_vnn(0,0)) + N_v[1]*(rData.BDF0*r_v(1,0) + rData.BDF1*r_vn(1,0) + rData.BDF2*r_vnn(1,0)) + N_v[2]*(rData.BDF0*r_v(2,0) + rData.BDF1*r_vn(2,0) + rData.BDF2*r_vnn(2,0)) + N_v[3]*(rData.BDF0*r_v(3,0) + rData.BDF1*r_vn(3,0) + rData.BDF2*r_vnn(3,0)) + N_v[4]*(rData.BDF0*r_v(4,0) + rData.BDF1*r_vn(4,0) + rData.BDF2*r_vnn(4,0)) + N_v[5]*(rData.BDF0*r_v(5,0) + rData.BDF1*r_vn(5,0) + rData.BDF2*r_vnn(5,0)) + N_v[6]*(rData.BDF0*r_v(6,0) + rData.BDF1*r_vn(6,0) + rData.BDF2*r_vnn(6,0)) + N_v[7]*(rData.BDF0*r_v(7,0) + rData.BDF1*r_vn(7,0) + rData.BDF2*r_vnn(7,0)) + N_v[8]*(rData.BDF0*r_v(8,0) + rData.BDF1*r_vn(8,0) + rData.BDF2*r_vnn(8,0)) + N_v[9]*(rData.BDF0*r_v(9,0) + rData.BDF1*r_vn(9,0) + rData.BDF2*r_vnn(9,0))); + const double crRHS3 = DN_v(0,0)*r_v(0,0) + DN_v(1,0)*r_v(1,0) + DN_v(2,0)*r_v(2,0) + DN_v(3,0)*r_v(3,0) + DN_v(4,0)*r_v(4,0) + DN_v(5,0)*r_v(5,0) + DN_v(6,0)*r_v(6,0) + DN_v(7,0)*r_v(7,0) + DN_v(8,0)*r_v(8,0) + DN_v(9,0)*r_v(9,0); + const double crRHS4 = N_v[0]*vconv(0,0) + N_v[1]*vconv(1,0) + N_v[2]*vconv(2,0) + N_v[3]*vconv(3,0) + N_v[4]*vconv(4,0) + N_v[5]*vconv(5,0) + N_v[6]*vconv(6,0) + N_v[7]*vconv(7,0) + N_v[8]*vconv(8,0) + N_v[9]*vconv(9,0); + const double crRHS5 = N_v[0]*vconv(0,1) + N_v[1]*vconv(1,1) + N_v[2]*vconv(2,1) + N_v[3]*vconv(3,1) + N_v[4]*vconv(4,1) + N_v[5]*vconv(5,1) + N_v[6]*vconv(6,1) + N_v[7]*vconv(7,1) + N_v[8]*vconv(8,1) + N_v[9]*vconv(9,1); + const double crRHS6 = N_v[0]*vconv(0,2) + N_v[1]*vconv(1,2) + N_v[2]*vconv(2,2) + N_v[3]*vconv(3,2) + N_v[4]*vconv(4,2) + N_v[5]*vconv(5,2) + N_v[6]*vconv(6,2) + N_v[7]*vconv(7,2) + N_v[8]*vconv(8,2) + N_v[9]*vconv(9,2); + const double crRHS7 = rho*(crRHS3*crRHS4 + crRHS5*(DN_v(0,1)*r_v(0,0) + DN_v(1,1)*r_v(1,0) + DN_v(2,1)*r_v(2,0) + DN_v(3,1)*r_v(3,0) + DN_v(4,1)*r_v(4,0) + DN_v(5,1)*r_v(5,0) + DN_v(6,1)*r_v(6,0) + DN_v(7,1)*r_v(7,0) + DN_v(8,1)*r_v(8,0) + DN_v(9,1)*r_v(9,0)) + crRHS6*(DN_v(0,2)*r_v(0,0) + DN_v(1,2)*r_v(1,0) + DN_v(2,2)*r_v(2,0) + DN_v(3,2)*r_v(3,0) + DN_v(4,2)*r_v(4,0) + DN_v(5,2)*r_v(5,0) + DN_v(6,2)*r_v(6,0) + DN_v(7,2)*r_v(7,0) + DN_v(8,2)*r_v(8,0) + DN_v(9,2)*r_v(9,0))); + const double crRHS8 = DN_v(0,1)*r_v(0,1) + DN_v(1,1)*r_v(1,1) + DN_v(2,1)*r_v(2,1) + DN_v(3,1)*r_v(3,1) + DN_v(4,1)*r_v(4,1) + DN_v(5,1)*r_v(5,1) + DN_v(6,1)*r_v(6,1) + DN_v(7,1)*r_v(7,1) + DN_v(8,1)*r_v(8,1) + DN_v(9,1)*r_v(9,1); + const double crRHS9 = DN_v(0,2)*r_v(0,2) + DN_v(1,2)*r_v(1,2) + DN_v(2,2)*r_v(2,2) + DN_v(3,2)*r_v(3,2) + DN_v(4,2)*r_v(4,2) + DN_v(5,2)*r_v(5,2) + DN_v(6,2)*r_v(6,2) + DN_v(7,2)*r_v(7,2) + DN_v(8,2)*r_v(8,2) + DN_v(9,2)*r_v(9,2); + const double crRHS10 = crRHS3 + crRHS8 + crRHS9; + const double crRHS11 = rho*stab_c2*std::sqrt(std::pow(crRHS4, 2) + std::pow(crRHS5, 2) + std::pow(crRHS6, 2)); + const double crRHS12 = crRHS10*(crRHS11*h/stab_c1 + mu); + const double crRHS13 = 1.0*C(0,0); + const double crRHS14 = DDN_v[0](0,0)*r_v(0,0); + const double crRHS15 = DDN_v[1](0,0)*r_v(1,0); + const double crRHS16 = DDN_v[2](0,0)*r_v(2,0); + const double crRHS17 = DDN_v[3](0,0)*r_v(3,0); + const double crRHS18 = DDN_v[4](0,0)*r_v(4,0); + const double crRHS19 = DDN_v[5](0,0)*r_v(5,0); + const double crRHS20 = DDN_v[6](0,0)*r_v(6,0); + const double crRHS21 = DDN_v[7](0,0)*r_v(7,0); + const double crRHS22 = DDN_v[8](0,0)*r_v(8,0); + const double crRHS23 = DDN_v[9](0,0)*r_v(9,0); + const double crRHS24 = 1.0*C(0,1); + const double crRHS25 = DDN_v[0](0,1)*r_v(0,1); + const double crRHS26 = DDN_v[1](0,1)*r_v(1,1); + const double crRHS27 = DDN_v[2](0,1)*r_v(2,1); + const double crRHS28 = DDN_v[3](0,1)*r_v(3,1); + const double crRHS29 = DDN_v[4](0,1)*r_v(4,1); + const double crRHS30 = DDN_v[5](0,1)*r_v(5,1); + const double crRHS31 = DDN_v[6](0,1)*r_v(6,1); + const double crRHS32 = DDN_v[7](0,1)*r_v(7,1); + const double crRHS33 = DDN_v[8](0,1)*r_v(8,1); + const double crRHS34 = DDN_v[9](0,1)*r_v(9,1); + const double crRHS35 = 1.0*C(0,2); + const double crRHS36 = DDN_v[0](0,2)*r_v(0,2); + const double crRHS37 = DDN_v[1](0,2)*r_v(1,2); + const double crRHS38 = DDN_v[2](0,2)*r_v(2,2); + const double crRHS39 = DDN_v[3](0,2)*r_v(3,2); + const double crRHS40 = DDN_v[4](0,2)*r_v(4,2); + const double crRHS41 = DDN_v[5](0,2)*r_v(5,2); + const double crRHS42 = DDN_v[6](0,2)*r_v(6,2); + const double crRHS43 = DDN_v[7](0,2)*r_v(7,2); + const double crRHS44 = DDN_v[8](0,2)*r_v(8,2); + const double crRHS45 = DDN_v[9](0,2)*r_v(9,2); + const double crRHS46 = 1.0*C(0,3); + const double crRHS47 = 1.0*C(0,5); + const double crRHS48 = 1.0*C(1,3); + const double crRHS49 = 1.0*C(1,5); + const double crRHS50 = 1.0*C(2,3); + const double crRHS51 = 1.0*C(2,5); + const double crRHS52 = DDN_v[0](0,0)*r_v(0,1) + DDN_v[0](0,1)*r_v(0,0); + const double crRHS53 = DDN_v[1](0,0)*r_v(1,1) + DDN_v[1](0,1)*r_v(1,0); + const double crRHS54 = DDN_v[2](0,0)*r_v(2,1) + DDN_v[2](0,1)*r_v(2,0); + const double crRHS55 = DDN_v[3](0,0)*r_v(3,1) + DDN_v[3](0,1)*r_v(3,0); + const double crRHS56 = DDN_v[4](0,0)*r_v(4,1) + DDN_v[4](0,1)*r_v(4,0); + const double crRHS57 = DDN_v[5](0,0)*r_v(5,1) + DDN_v[5](0,1)*r_v(5,0); + const double crRHS58 = DDN_v[6](0,0)*r_v(6,1) + DDN_v[6](0,1)*r_v(6,0); + const double crRHS59 = DDN_v[7](0,0)*r_v(7,1) + DDN_v[7](0,1)*r_v(7,0); + const double crRHS60 = DDN_v[8](0,0)*r_v(8,1) + DDN_v[8](0,1)*r_v(8,0); + const double crRHS61 = DDN_v[9](0,0)*r_v(9,1) + DDN_v[9](0,1)*r_v(9,0); + const double crRHS62 = DDN_v[0](0,1)*r_v(0,2) + DDN_v[0](0,2)*r_v(0,1); + const double crRHS63 = 1.0*C(0,4); + const double crRHS64 = DDN_v[1](0,1)*r_v(1,2) + DDN_v[1](0,2)*r_v(1,1); + const double crRHS65 = DDN_v[2](0,1)*r_v(2,2) + DDN_v[2](0,2)*r_v(2,1); + const double crRHS66 = DDN_v[3](0,1)*r_v(3,2) + DDN_v[3](0,2)*r_v(3,1); + const double crRHS67 = DDN_v[4](0,1)*r_v(4,2) + DDN_v[4](0,2)*r_v(4,1); + const double crRHS68 = DDN_v[5](0,1)*r_v(5,2) + DDN_v[5](0,2)*r_v(5,1); + const double crRHS69 = DDN_v[6](0,1)*r_v(6,2) + DDN_v[6](0,2)*r_v(6,1); + const double crRHS70 = DDN_v[7](0,1)*r_v(7,2) + DDN_v[7](0,2)*r_v(7,1); + const double crRHS71 = DDN_v[8](0,1)*r_v(8,2) + DDN_v[8](0,2)*r_v(8,1); + const double crRHS72 = DDN_v[9](0,1)*r_v(9,2) + DDN_v[9](0,2)*r_v(9,1); + const double crRHS73 = DDN_v[0](0,0)*r_v(0,2) + DDN_v[0](0,2)*r_v(0,0); + const double crRHS74 = DDN_v[1](0,0)*r_v(1,2) + DDN_v[1](0,2)*r_v(1,0); + const double crRHS75 = DDN_v[2](0,0)*r_v(2,2) + DDN_v[2](0,2)*r_v(2,0); + const double crRHS76 = DDN_v[3](0,0)*r_v(3,2) + DDN_v[3](0,2)*r_v(3,0); + const double crRHS77 = DDN_v[4](0,0)*r_v(4,2) + DDN_v[4](0,2)*r_v(4,0); + const double crRHS78 = DDN_v[5](0,0)*r_v(5,2) + DDN_v[5](0,2)*r_v(5,0); + const double crRHS79 = DDN_v[6](0,0)*r_v(6,2) + DDN_v[6](0,2)*r_v(6,0); + const double crRHS80 = DDN_v[7](0,0)*r_v(7,2) + DDN_v[7](0,2)*r_v(7,0); + const double crRHS81 = DDN_v[8](0,0)*r_v(8,2) + DDN_v[8](0,2)*r_v(8,0); + const double crRHS82 = DDN_v[9](0,0)*r_v(9,2) + DDN_v[9](0,2)*r_v(9,0); + const double crRHS83 = 1.0*C(3,3); + const double crRHS84 = 1.0*C(3,4); + const double crRHS85 = 1.0*C(3,5); + const double crRHS86 = 1.0*C(4,5); + const double crRHS87 = 1.0*C(5,5); + const double crRHS88 = 1.0/(crRHS11/h + dyn_tau*rho/rData.DeltaTime + mu*stab_c1/std::pow(h, 2)); + const double crRHS89 = crRHS88*(-DN_p(0,0)*r_p[0] - DN_p(1,0)*r_p[1] - DN_p(2,0)*r_p[2] - DN_p(3,0)*r_p[3] + crRHS1 + crRHS13*crRHS14 + crRHS13*crRHS15 + crRHS13*crRHS16 + crRHS13*crRHS17 + crRHS13*crRHS18 + crRHS13*crRHS19 + crRHS13*crRHS20 + crRHS13*crRHS21 + crRHS13*crRHS22 + crRHS13*crRHS23 + crRHS14*crRHS46 + crRHS14*crRHS47 + crRHS15*crRHS46 + crRHS15*crRHS47 + crRHS16*crRHS46 + crRHS16*crRHS47 + crRHS17*crRHS46 + crRHS17*crRHS47 + crRHS18*crRHS46 + crRHS18*crRHS47 + crRHS19*crRHS46 + crRHS19*crRHS47 - crRHS2 + crRHS20*crRHS46 + crRHS20*crRHS47 + crRHS21*crRHS46 + crRHS21*crRHS47 + crRHS22*crRHS46 + crRHS22*crRHS47 + crRHS23*crRHS46 + crRHS23*crRHS47 + crRHS24*crRHS25 + crRHS24*crRHS26 + crRHS24*crRHS27 + crRHS24*crRHS28 + crRHS24*crRHS29 + crRHS24*crRHS30 + crRHS24*crRHS31 + crRHS24*crRHS32 + crRHS24*crRHS33 + crRHS24*crRHS34 + crRHS25*crRHS48 + crRHS25*crRHS49 + crRHS26*crRHS48 + crRHS26*crRHS49 + crRHS27*crRHS48 + crRHS27*crRHS49 + crRHS28*crRHS48 + crRHS28*crRHS49 + crRHS29*crRHS48 + crRHS29*crRHS49 + crRHS30*crRHS48 + crRHS30*crRHS49 + crRHS31*crRHS48 + crRHS31*crRHS49 + crRHS32*crRHS48 + crRHS32*crRHS49 + crRHS33*crRHS48 + crRHS33*crRHS49 + crRHS34*crRHS48 + crRHS34*crRHS49 + crRHS35*crRHS36 + crRHS35*crRHS37 + crRHS35*crRHS38 + crRHS35*crRHS39 + crRHS35*crRHS40 + crRHS35*crRHS41 + crRHS35*crRHS42 + crRHS35*crRHS43 + crRHS35*crRHS44 + crRHS35*crRHS45 + crRHS36*crRHS50 + crRHS36*crRHS51 + crRHS37*crRHS50 + crRHS37*crRHS51 + crRHS38*crRHS50 + crRHS38*crRHS51 + crRHS39*crRHS50 + crRHS39*crRHS51 + crRHS40*crRHS50 + crRHS40*crRHS51 + crRHS41*crRHS50 + crRHS41*crRHS51 + crRHS42*crRHS50 + crRHS42*crRHS51 + crRHS43*crRHS50 + crRHS43*crRHS51 + crRHS44*crRHS50 + crRHS44*crRHS51 + crRHS45*crRHS50 + crRHS45*crRHS51 + crRHS46*crRHS52 + crRHS46*crRHS53 + crRHS46*crRHS54 + crRHS46*crRHS55 + crRHS46*crRHS56 + crRHS46*crRHS57 + crRHS46*crRHS58 + crRHS46*crRHS59 + crRHS46*crRHS60 + crRHS46*crRHS61 + crRHS47*crRHS73 + crRHS47*crRHS74 + crRHS47*crRHS75 + crRHS47*crRHS76 + crRHS47*crRHS77 + crRHS47*crRHS78 + crRHS47*crRHS79 + crRHS47*crRHS80 + crRHS47*crRHS81 + crRHS47*crRHS82 + crRHS52*crRHS83 + crRHS52*crRHS85 + crRHS53*crRHS83 + crRHS53*crRHS85 + crRHS54*crRHS83 + crRHS54*crRHS85 + crRHS55*crRHS83 + crRHS55*crRHS85 + crRHS56*crRHS83 + crRHS56*crRHS85 + crRHS57*crRHS83 + crRHS57*crRHS85 + crRHS58*crRHS83 + crRHS58*crRHS85 + crRHS59*crRHS83 + crRHS59*crRHS85 + crRHS60*crRHS83 + crRHS60*crRHS85 + crRHS61*crRHS83 + crRHS61*crRHS85 + crRHS62*crRHS63 + crRHS62*crRHS84 + crRHS62*crRHS86 + crRHS63*crRHS64 + crRHS63*crRHS65 + crRHS63*crRHS66 + crRHS63*crRHS67 + crRHS63*crRHS68 + crRHS63*crRHS69 + crRHS63*crRHS70 + crRHS63*crRHS71 + crRHS63*crRHS72 + crRHS64*crRHS84 + crRHS64*crRHS86 + crRHS65*crRHS84 + crRHS65*crRHS86 + crRHS66*crRHS84 + crRHS66*crRHS86 + crRHS67*crRHS84 + crRHS67*crRHS86 + crRHS68*crRHS84 + crRHS68*crRHS86 + crRHS69*crRHS84 + crRHS69*crRHS86 - crRHS7 + crRHS70*crRHS84 + crRHS70*crRHS86 + crRHS71*crRHS84 + crRHS71*crRHS86 + crRHS72*crRHS84 + crRHS72*crRHS86 + crRHS73*crRHS85 + crRHS73*crRHS87 + crRHS74*crRHS85 + crRHS74*crRHS87 + crRHS75*crRHS85 + crRHS75*crRHS87 + crRHS76*crRHS85 + crRHS76*crRHS87 + crRHS77*crRHS85 + crRHS77*crRHS87 + crRHS78*crRHS85 + crRHS78*crRHS87 + crRHS79*crRHS85 + crRHS79*crRHS87 + crRHS80*crRHS85 + crRHS80*crRHS87 + crRHS81*crRHS85 + crRHS81*crRHS87 + crRHS82*crRHS85 + crRHS82*crRHS87); + const double crRHS90 = rho*(DN_v(0,0)*vconv(0,0) + DN_v(0,1)*vconv(0,1) + DN_v(0,2)*vconv(0,2) + DN_v(1,0)*vconv(1,0) + DN_v(1,1)*vconv(1,1) + DN_v(1,2)*vconv(1,2) + DN_v(2,0)*vconv(2,0) + DN_v(2,1)*vconv(2,1) + DN_v(2,2)*vconv(2,2) + DN_v(3,0)*vconv(3,0) + DN_v(3,1)*vconv(3,1) + DN_v(3,2)*vconv(3,2) + DN_v(4,0)*vconv(4,0) + DN_v(4,1)*vconv(4,1) + DN_v(4,2)*vconv(4,2) + DN_v(5,0)*vconv(5,0) + DN_v(5,1)*vconv(5,1) + DN_v(5,2)*vconv(5,2) + DN_v(6,0)*vconv(6,0) + DN_v(6,1)*vconv(6,1) + DN_v(6,2)*vconv(6,2) + DN_v(7,0)*vconv(7,0) + DN_v(7,1)*vconv(7,1) + DN_v(7,2)*vconv(7,2) + DN_v(8,0)*vconv(8,0) + DN_v(8,1)*vconv(8,1) + DN_v(8,2)*vconv(8,2) + DN_v(9,0)*vconv(9,0) + DN_v(9,1)*vconv(9,1) + DN_v(9,2)*vconv(9,2)); + const double crRHS91 = N_v[0]*crRHS90; + const double crRHS92 = rho*(DN_v(0,0)*crRHS4 + DN_v(0,1)*crRHS5 + DN_v(0,2)*crRHS6); + const double crRHS93 = rho*(N_v[0]*r_f(0,1) + N_v[1]*r_f(1,1) + N_v[2]*r_f(2,1) + N_v[3]*r_f(3,1) + N_v[4]*r_f(4,1) + N_v[5]*r_f(5,1) + N_v[6]*r_f(6,1) + N_v[7]*r_f(7,1) + N_v[8]*r_f(8,1) + N_v[9]*r_f(9,1)); + const double crRHS94 = rho*(N_v[0]*(rData.BDF0*r_v(0,1) + rData.BDF1*r_vn(0,1) + rData.BDF2*r_vnn(0,1)) + N_v[1]*(rData.BDF0*r_v(1,1) + rData.BDF1*r_vn(1,1) + rData.BDF2*r_vnn(1,1)) + N_v[2]*(rData.BDF0*r_v(2,1) + rData.BDF1*r_vn(2,1) + rData.BDF2*r_vnn(2,1)) + N_v[3]*(rData.BDF0*r_v(3,1) + rData.BDF1*r_vn(3,1) + rData.BDF2*r_vnn(3,1)) + N_v[4]*(rData.BDF0*r_v(4,1) + rData.BDF1*r_vn(4,1) + rData.BDF2*r_vnn(4,1)) + N_v[5]*(rData.BDF0*r_v(5,1) + rData.BDF1*r_vn(5,1) + rData.BDF2*r_vnn(5,1)) + N_v[6]*(rData.BDF0*r_v(6,1) + rData.BDF1*r_vn(6,1) + rData.BDF2*r_vnn(6,1)) + N_v[7]*(rData.BDF0*r_v(7,1) + rData.BDF1*r_vn(7,1) + rData.BDF2*r_vnn(7,1)) + N_v[8]*(rData.BDF0*r_v(8,1) + rData.BDF1*r_vn(8,1) + rData.BDF2*r_vnn(8,1)) + N_v[9]*(rData.BDF0*r_v(9,1) + rData.BDF1*r_vn(9,1) + rData.BDF2*r_vnn(9,1))); + const double crRHS95 = rho*(crRHS4*(DN_v(0,0)*r_v(0,1) + DN_v(1,0)*r_v(1,1) + DN_v(2,0)*r_v(2,1) + DN_v(3,0)*r_v(3,1) + DN_v(4,0)*r_v(4,1) + DN_v(5,0)*r_v(5,1) + DN_v(6,0)*r_v(6,1) + DN_v(7,0)*r_v(7,1) + DN_v(8,0)*r_v(8,1) + DN_v(9,0)*r_v(9,1)) + crRHS5*crRHS8 + crRHS6*(DN_v(0,2)*r_v(0,1) + DN_v(1,2)*r_v(1,1) + DN_v(2,2)*r_v(2,1) + DN_v(3,2)*r_v(3,1) + DN_v(4,2)*r_v(4,1) + DN_v(5,2)*r_v(5,1) + DN_v(6,2)*r_v(6,1) + DN_v(7,2)*r_v(7,1) + DN_v(8,2)*r_v(8,1) + DN_v(9,2)*r_v(9,1))); + const double crRHS96 = DDN_v[0](1,0)*r_v(0,0); + const double crRHS97 = DDN_v[1](1,0)*r_v(1,0); + const double crRHS98 = DDN_v[2](1,0)*r_v(2,0); + const double crRHS99 = DDN_v[3](1,0)*r_v(3,0); + const double crRHS100 = DDN_v[4](1,0)*r_v(4,0); + const double crRHS101 = DDN_v[5](1,0)*r_v(5,0); + const double crRHS102 = DDN_v[6](1,0)*r_v(6,0); + const double crRHS103 = DDN_v[7](1,0)*r_v(7,0); + const double crRHS104 = DDN_v[8](1,0)*r_v(8,0); + const double crRHS105 = DDN_v[9](1,0)*r_v(9,0); + const double crRHS106 = 1.0*C(1,1); + const double crRHS107 = DDN_v[0](1,1)*r_v(0,1); + const double crRHS108 = DDN_v[1](1,1)*r_v(1,1); + const double crRHS109 = DDN_v[2](1,1)*r_v(2,1); + const double crRHS110 = DDN_v[3](1,1)*r_v(3,1); + const double crRHS111 = DDN_v[4](1,1)*r_v(4,1); + const double crRHS112 = DDN_v[5](1,1)*r_v(5,1); + const double crRHS113 = DDN_v[6](1,1)*r_v(6,1); + const double crRHS114 = DDN_v[7](1,1)*r_v(7,1); + const double crRHS115 = DDN_v[8](1,1)*r_v(8,1); + const double crRHS116 = DDN_v[9](1,1)*r_v(9,1); + const double crRHS117 = 1.0*C(1,2); + const double crRHS118 = DDN_v[0](1,2)*r_v(0,2); + const double crRHS119 = DDN_v[1](1,2)*r_v(1,2); + const double crRHS120 = DDN_v[2](1,2)*r_v(2,2); + const double crRHS121 = DDN_v[3](1,2)*r_v(3,2); + const double crRHS122 = DDN_v[4](1,2)*r_v(4,2); + const double crRHS123 = DDN_v[5](1,2)*r_v(5,2); + const double crRHS124 = DDN_v[6](1,2)*r_v(6,2); + const double crRHS125 = DDN_v[7](1,2)*r_v(7,2); + const double crRHS126 = DDN_v[8](1,2)*r_v(8,2); + const double crRHS127 = DDN_v[9](1,2)*r_v(9,2); + const double crRHS128 = 1.0*C(1,4); + const double crRHS129 = 1.0*C(2,4); + const double crRHS130 = DDN_v[0](1,0)*r_v(0,1) + DDN_v[0](1,1)*r_v(0,0); + const double crRHS131 = DDN_v[1](1,0)*r_v(1,1) + DDN_v[1](1,1)*r_v(1,0); + const double crRHS132 = DDN_v[2](1,0)*r_v(2,1) + DDN_v[2](1,1)*r_v(2,0); + const double crRHS133 = DDN_v[3](1,0)*r_v(3,1) + DDN_v[3](1,1)*r_v(3,0); + const double crRHS134 = DDN_v[4](1,0)*r_v(4,1) + DDN_v[4](1,1)*r_v(4,0); + const double crRHS135 = DDN_v[5](1,0)*r_v(5,1) + DDN_v[5](1,1)*r_v(5,0); + const double crRHS136 = DDN_v[6](1,0)*r_v(6,1) + DDN_v[6](1,1)*r_v(6,0); + const double crRHS137 = DDN_v[7](1,0)*r_v(7,1) + DDN_v[7](1,1)*r_v(7,0); + const double crRHS138 = DDN_v[8](1,0)*r_v(8,1) + DDN_v[8](1,1)*r_v(8,0); + const double crRHS139 = DDN_v[9](1,0)*r_v(9,1) + DDN_v[9](1,1)*r_v(9,0); + const double crRHS140 = DDN_v[0](1,1)*r_v(0,2) + DDN_v[0](1,2)*r_v(0,1); + const double crRHS141 = DDN_v[1](1,1)*r_v(1,2) + DDN_v[1](1,2)*r_v(1,1); + const double crRHS142 = DDN_v[2](1,1)*r_v(2,2) + DDN_v[2](1,2)*r_v(2,1); + const double crRHS143 = DDN_v[3](1,1)*r_v(3,2) + DDN_v[3](1,2)*r_v(3,1); + const double crRHS144 = DDN_v[4](1,1)*r_v(4,2) + DDN_v[4](1,2)*r_v(4,1); + const double crRHS145 = DDN_v[5](1,1)*r_v(5,2) + DDN_v[5](1,2)*r_v(5,1); + const double crRHS146 = DDN_v[6](1,1)*r_v(6,2) + DDN_v[6](1,2)*r_v(6,1); + const double crRHS147 = DDN_v[7](1,1)*r_v(7,2) + DDN_v[7](1,2)*r_v(7,1); + const double crRHS148 = DDN_v[8](1,1)*r_v(8,2) + DDN_v[8](1,2)*r_v(8,1); + const double crRHS149 = DDN_v[9](1,1)*r_v(9,2) + DDN_v[9](1,2)*r_v(9,1); + const double crRHS150 = DDN_v[0](1,0)*r_v(0,2) + DDN_v[0](1,2)*r_v(0,0); + const double crRHS151 = DDN_v[1](1,0)*r_v(1,2) + DDN_v[1](1,2)*r_v(1,0); + const double crRHS152 = DDN_v[2](1,0)*r_v(2,2) + DDN_v[2](1,2)*r_v(2,0); + const double crRHS153 = DDN_v[3](1,0)*r_v(3,2) + DDN_v[3](1,2)*r_v(3,0); + const double crRHS154 = DDN_v[4](1,0)*r_v(4,2) + DDN_v[4](1,2)*r_v(4,0); + const double crRHS155 = DDN_v[5](1,0)*r_v(5,2) + DDN_v[5](1,2)*r_v(5,0); + const double crRHS156 = DDN_v[6](1,0)*r_v(6,2) + DDN_v[6](1,2)*r_v(6,0); + const double crRHS157 = DDN_v[7](1,0)*r_v(7,2) + DDN_v[7](1,2)*r_v(7,0); + const double crRHS158 = DDN_v[8](1,0)*r_v(8,2) + DDN_v[8](1,2)*r_v(8,0); + const double crRHS159 = DDN_v[9](1,0)*r_v(9,2) + DDN_v[9](1,2)*r_v(9,0); + const double crRHS160 = 1.0*C(4,4); + const double crRHS161 = crRHS88*(-DN_p(0,1)*r_p[0] - DN_p(1,1)*r_p[1] - DN_p(2,1)*r_p[2] - DN_p(3,1)*r_p[3] + crRHS100*crRHS24 + crRHS100*crRHS46 + crRHS100*crRHS63 + crRHS101*crRHS24 + crRHS101*crRHS46 + crRHS101*crRHS63 + crRHS102*crRHS24 + crRHS102*crRHS46 + crRHS102*crRHS63 + crRHS103*crRHS24 + crRHS103*crRHS46 + crRHS103*crRHS63 + crRHS104*crRHS24 + crRHS104*crRHS46 + crRHS104*crRHS63 + crRHS105*crRHS24 + crRHS105*crRHS46 + crRHS105*crRHS63 + crRHS106*crRHS107 + crRHS106*crRHS108 + crRHS106*crRHS109 + crRHS106*crRHS110 + crRHS106*crRHS111 + crRHS106*crRHS112 + crRHS106*crRHS113 + crRHS106*crRHS114 + crRHS106*crRHS115 + crRHS106*crRHS116 + crRHS107*crRHS128 + crRHS107*crRHS48 + crRHS108*crRHS128 + crRHS108*crRHS48 + crRHS109*crRHS128 + crRHS109*crRHS48 + crRHS110*crRHS128 + crRHS110*crRHS48 + crRHS111*crRHS128 + crRHS111*crRHS48 + crRHS112*crRHS128 + crRHS112*crRHS48 + crRHS113*crRHS128 + crRHS113*crRHS48 + crRHS114*crRHS128 + crRHS114*crRHS48 + crRHS115*crRHS128 + crRHS115*crRHS48 + crRHS116*crRHS128 + crRHS116*crRHS48 + crRHS117*crRHS118 + crRHS117*crRHS119 + crRHS117*crRHS120 + crRHS117*crRHS121 + crRHS117*crRHS122 + crRHS117*crRHS123 + crRHS117*crRHS124 + crRHS117*crRHS125 + crRHS117*crRHS126 + crRHS117*crRHS127 + crRHS118*crRHS129 + crRHS118*crRHS50 + crRHS119*crRHS129 + crRHS119*crRHS50 + crRHS120*crRHS129 + crRHS120*crRHS50 + crRHS121*crRHS129 + crRHS121*crRHS50 + crRHS122*crRHS129 + crRHS122*crRHS50 + crRHS123*crRHS129 + crRHS123*crRHS50 + crRHS124*crRHS129 + crRHS124*crRHS50 + crRHS125*crRHS129 + crRHS125*crRHS50 + crRHS126*crRHS129 + crRHS126*crRHS50 + crRHS127*crRHS129 + crRHS127*crRHS50 + crRHS128*crRHS140 + crRHS128*crRHS141 + crRHS128*crRHS142 + crRHS128*crRHS143 + crRHS128*crRHS144 + crRHS128*crRHS145 + crRHS128*crRHS146 + crRHS128*crRHS147 + crRHS128*crRHS148 + crRHS128*crRHS149 + crRHS130*crRHS48 + crRHS130*crRHS83 + crRHS130*crRHS84 + crRHS131*crRHS48 + crRHS131*crRHS83 + crRHS131*crRHS84 + crRHS132*crRHS48 + crRHS132*crRHS83 + crRHS132*crRHS84 + crRHS133*crRHS48 + crRHS133*crRHS83 + crRHS133*crRHS84 + crRHS134*crRHS48 + crRHS134*crRHS83 + crRHS134*crRHS84 + crRHS135*crRHS48 + crRHS135*crRHS83 + crRHS135*crRHS84 + crRHS136*crRHS48 + crRHS136*crRHS83 + crRHS136*crRHS84 + crRHS137*crRHS48 + crRHS137*crRHS83 + crRHS137*crRHS84 + crRHS138*crRHS48 + crRHS138*crRHS83 + crRHS138*crRHS84 + crRHS139*crRHS48 + crRHS139*crRHS83 + crRHS139*crRHS84 + crRHS140*crRHS160 + crRHS140*crRHS84 + crRHS141*crRHS160 + crRHS141*crRHS84 + crRHS142*crRHS160 + crRHS142*crRHS84 + crRHS143*crRHS160 + crRHS143*crRHS84 + crRHS144*crRHS160 + crRHS144*crRHS84 + crRHS145*crRHS160 + crRHS145*crRHS84 + crRHS146*crRHS160 + crRHS146*crRHS84 + crRHS147*crRHS160 + crRHS147*crRHS84 + crRHS148*crRHS160 + crRHS148*crRHS84 + crRHS149*crRHS160 + crRHS149*crRHS84 + crRHS150*crRHS49 + crRHS150*crRHS85 + crRHS150*crRHS86 + crRHS151*crRHS49 + crRHS151*crRHS85 + crRHS151*crRHS86 + crRHS152*crRHS49 + crRHS152*crRHS85 + crRHS152*crRHS86 + crRHS153*crRHS49 + crRHS153*crRHS85 + crRHS153*crRHS86 + crRHS154*crRHS49 + crRHS154*crRHS85 + crRHS154*crRHS86 + crRHS155*crRHS49 + crRHS155*crRHS85 + crRHS155*crRHS86 + crRHS156*crRHS49 + crRHS156*crRHS85 + crRHS156*crRHS86 + crRHS157*crRHS49 + crRHS157*crRHS85 + crRHS157*crRHS86 + crRHS158*crRHS49 + crRHS158*crRHS85 + crRHS158*crRHS86 + crRHS159*crRHS49 + crRHS159*crRHS85 + crRHS159*crRHS86 + crRHS24*crRHS96 + crRHS24*crRHS97 + crRHS24*crRHS98 + crRHS24*crRHS99 + crRHS46*crRHS96 + crRHS46*crRHS97 + crRHS46*crRHS98 + crRHS46*crRHS99 + crRHS63*crRHS96 + crRHS63*crRHS97 + crRHS63*crRHS98 + crRHS63*crRHS99 + crRHS93 - crRHS94 - crRHS95); + const double crRHS162 = rho*(N_v[0]*r_f(0,2) + N_v[1]*r_f(1,2) + N_v[2]*r_f(2,2) + N_v[3]*r_f(3,2) + N_v[4]*r_f(4,2) + N_v[5]*r_f(5,2) + N_v[6]*r_f(6,2) + N_v[7]*r_f(7,2) + N_v[8]*r_f(8,2) + N_v[9]*r_f(9,2)); + const double crRHS163 = rho*(N_v[0]*(rData.BDF0*r_v(0,2) + rData.BDF1*r_vn(0,2) + rData.BDF2*r_vnn(0,2)) + N_v[1]*(rData.BDF0*r_v(1,2) + rData.BDF1*r_vn(1,2) + rData.BDF2*r_vnn(1,2)) + N_v[2]*(rData.BDF0*r_v(2,2) + rData.BDF1*r_vn(2,2) + rData.BDF2*r_vnn(2,2)) + N_v[3]*(rData.BDF0*r_v(3,2) + rData.BDF1*r_vn(3,2) + rData.BDF2*r_vnn(3,2)) + N_v[4]*(rData.BDF0*r_v(4,2) + rData.BDF1*r_vn(4,2) + rData.BDF2*r_vnn(4,2)) + N_v[5]*(rData.BDF0*r_v(5,2) + rData.BDF1*r_vn(5,2) + rData.BDF2*r_vnn(5,2)) + N_v[6]*(rData.BDF0*r_v(6,2) + rData.BDF1*r_vn(6,2) + rData.BDF2*r_vnn(6,2)) + N_v[7]*(rData.BDF0*r_v(7,2) + rData.BDF1*r_vn(7,2) + rData.BDF2*r_vnn(7,2)) + N_v[8]*(rData.BDF0*r_v(8,2) + rData.BDF1*r_vn(8,2) + rData.BDF2*r_vnn(8,2)) + N_v[9]*(rData.BDF0*r_v(9,2) + rData.BDF1*r_vn(9,2) + rData.BDF2*r_vnn(9,2))); + const double crRHS164 = rho*(crRHS4*(DN_v(0,0)*r_v(0,2) + DN_v(1,0)*r_v(1,2) + DN_v(2,0)*r_v(2,2) + DN_v(3,0)*r_v(3,2) + DN_v(4,0)*r_v(4,2) + DN_v(5,0)*r_v(5,2) + DN_v(6,0)*r_v(6,2) + DN_v(7,0)*r_v(7,2) + DN_v(8,0)*r_v(8,2) + DN_v(9,0)*r_v(9,2)) + crRHS5*(DN_v(0,1)*r_v(0,2) + DN_v(1,1)*r_v(1,2) + DN_v(2,1)*r_v(2,2) + DN_v(3,1)*r_v(3,2) + DN_v(4,1)*r_v(4,2) + DN_v(5,1)*r_v(5,2) + DN_v(6,1)*r_v(6,2) + DN_v(7,1)*r_v(7,2) + DN_v(8,1)*r_v(8,2) + DN_v(9,1)*r_v(9,2)) + crRHS6*crRHS9); + const double crRHS165 = DDN_v[0](2,0)*r_v(0,0); + const double crRHS166 = DDN_v[1](2,0)*r_v(1,0); + const double crRHS167 = DDN_v[2](2,0)*r_v(2,0); + const double crRHS168 = DDN_v[3](2,0)*r_v(3,0); + const double crRHS169 = DDN_v[4](2,0)*r_v(4,0); + const double crRHS170 = DDN_v[5](2,0)*r_v(5,0); + const double crRHS171 = DDN_v[6](2,0)*r_v(6,0); + const double crRHS172 = DDN_v[7](2,0)*r_v(7,0); + const double crRHS173 = DDN_v[8](2,0)*r_v(8,0); + const double crRHS174 = DDN_v[9](2,0)*r_v(9,0); + const double crRHS175 = DDN_v[0](2,1)*r_v(0,1); + const double crRHS176 = DDN_v[1](2,1)*r_v(1,1); + const double crRHS177 = DDN_v[2](2,1)*r_v(2,1); + const double crRHS178 = DDN_v[3](2,1)*r_v(3,1); + const double crRHS179 = DDN_v[4](2,1)*r_v(4,1); + const double crRHS180 = DDN_v[5](2,1)*r_v(5,1); + const double crRHS181 = DDN_v[6](2,1)*r_v(6,1); + const double crRHS182 = DDN_v[7](2,1)*r_v(7,1); + const double crRHS183 = DDN_v[8](2,1)*r_v(8,1); + const double crRHS184 = DDN_v[9](2,1)*r_v(9,1); + const double crRHS185 = 1.0*C(2,2); + const double crRHS186 = DDN_v[0](2,2)*r_v(0,2); + const double crRHS187 = DDN_v[1](2,2)*r_v(1,2); + const double crRHS188 = DDN_v[2](2,2)*r_v(2,2); + const double crRHS189 = DDN_v[3](2,2)*r_v(3,2); + const double crRHS190 = DDN_v[4](2,2)*r_v(4,2); + const double crRHS191 = DDN_v[5](2,2)*r_v(5,2); + const double crRHS192 = DDN_v[6](2,2)*r_v(6,2); + const double crRHS193 = DDN_v[7](2,2)*r_v(7,2); + const double crRHS194 = DDN_v[8](2,2)*r_v(8,2); + const double crRHS195 = DDN_v[9](2,2)*r_v(9,2); + const double crRHS196 = DDN_v[0](2,0)*r_v(0,1) + DDN_v[0](2,1)*r_v(0,0); + const double crRHS197 = DDN_v[1](2,0)*r_v(1,1) + DDN_v[1](2,1)*r_v(1,0); + const double crRHS198 = DDN_v[2](2,0)*r_v(2,1) + DDN_v[2](2,1)*r_v(2,0); + const double crRHS199 = DDN_v[3](2,0)*r_v(3,1) + DDN_v[3](2,1)*r_v(3,0); + const double crRHS200 = DDN_v[4](2,0)*r_v(4,1) + DDN_v[4](2,1)*r_v(4,0); + const double crRHS201 = DDN_v[5](2,0)*r_v(5,1) + DDN_v[5](2,1)*r_v(5,0); + const double crRHS202 = DDN_v[6](2,0)*r_v(6,1) + DDN_v[6](2,1)*r_v(6,0); + const double crRHS203 = DDN_v[7](2,0)*r_v(7,1) + DDN_v[7](2,1)*r_v(7,0); + const double crRHS204 = DDN_v[8](2,0)*r_v(8,1) + DDN_v[8](2,1)*r_v(8,0); + const double crRHS205 = DDN_v[9](2,0)*r_v(9,1) + DDN_v[9](2,1)*r_v(9,0); + const double crRHS206 = DDN_v[0](2,1)*r_v(0,2) + DDN_v[0](2,2)*r_v(0,1); + const double crRHS207 = DDN_v[1](2,1)*r_v(1,2) + DDN_v[1](2,2)*r_v(1,1); + const double crRHS208 = DDN_v[2](2,1)*r_v(2,2) + DDN_v[2](2,2)*r_v(2,1); + const double crRHS209 = DDN_v[3](2,1)*r_v(3,2) + DDN_v[3](2,2)*r_v(3,1); + const double crRHS210 = DDN_v[4](2,1)*r_v(4,2) + DDN_v[4](2,2)*r_v(4,1); + const double crRHS211 = DDN_v[5](2,1)*r_v(5,2) + DDN_v[5](2,2)*r_v(5,1); + const double crRHS212 = DDN_v[6](2,1)*r_v(6,2) + DDN_v[6](2,2)*r_v(6,1); + const double crRHS213 = DDN_v[7](2,1)*r_v(7,2) + DDN_v[7](2,2)*r_v(7,1); + const double crRHS214 = DDN_v[8](2,1)*r_v(8,2) + DDN_v[8](2,2)*r_v(8,1); + const double crRHS215 = DDN_v[9](2,1)*r_v(9,2) + DDN_v[9](2,2)*r_v(9,1); + const double crRHS216 = DDN_v[0](2,0)*r_v(0,2) + DDN_v[0](2,2)*r_v(0,0); + const double crRHS217 = DDN_v[1](2,0)*r_v(1,2) + DDN_v[1](2,2)*r_v(1,0); + const double crRHS218 = DDN_v[2](2,0)*r_v(2,2) + DDN_v[2](2,2)*r_v(2,0); + const double crRHS219 = DDN_v[3](2,0)*r_v(3,2) + DDN_v[3](2,2)*r_v(3,0); + const double crRHS220 = DDN_v[4](2,0)*r_v(4,2) + DDN_v[4](2,2)*r_v(4,0); + const double crRHS221 = DDN_v[5](2,0)*r_v(5,2) + DDN_v[5](2,2)*r_v(5,0); + const double crRHS222 = DDN_v[6](2,0)*r_v(6,2) + DDN_v[6](2,2)*r_v(6,0); + const double crRHS223 = DDN_v[7](2,0)*r_v(7,2) + DDN_v[7](2,2)*r_v(7,0); + const double crRHS224 = DDN_v[8](2,0)*r_v(8,2) + DDN_v[8](2,2)*r_v(8,0); + const double crRHS225 = DDN_v[9](2,0)*r_v(9,2) + DDN_v[9](2,2)*r_v(9,0); + const double crRHS226 = crRHS88*(-DN_p(0,2)*r_p[0] - DN_p(1,2)*r_p[1] - DN_p(2,2)*r_p[2] - DN_p(3,2)*r_p[3] + crRHS117*crRHS175 + crRHS117*crRHS176 + crRHS117*crRHS177 + crRHS117*crRHS178 + crRHS117*crRHS179 + crRHS117*crRHS180 + crRHS117*crRHS181 + crRHS117*crRHS182 + crRHS117*crRHS183 + crRHS117*crRHS184 + crRHS128*crRHS175 + crRHS128*crRHS176 + crRHS128*crRHS177 + crRHS128*crRHS178 + crRHS128*crRHS179 + crRHS128*crRHS180 + crRHS128*crRHS181 + crRHS128*crRHS182 + crRHS128*crRHS183 + crRHS128*crRHS184 + crRHS129*crRHS186 + crRHS129*crRHS187 + crRHS129*crRHS188 + crRHS129*crRHS189 + crRHS129*crRHS190 + crRHS129*crRHS191 + crRHS129*crRHS192 + crRHS129*crRHS193 + crRHS129*crRHS194 + crRHS129*crRHS195 + crRHS129*crRHS206 + crRHS129*crRHS207 + crRHS129*crRHS208 + crRHS129*crRHS209 + crRHS129*crRHS210 + crRHS129*crRHS211 + crRHS129*crRHS212 + crRHS129*crRHS213 + crRHS129*crRHS214 + crRHS129*crRHS215 + crRHS160*crRHS206 + crRHS160*crRHS207 + crRHS160*crRHS208 + crRHS160*crRHS209 + crRHS160*crRHS210 + crRHS160*crRHS211 + crRHS160*crRHS212 + crRHS160*crRHS213 + crRHS160*crRHS214 + crRHS160*crRHS215 + crRHS162 - crRHS163 - crRHS164 + crRHS165*crRHS35 + crRHS165*crRHS47 + crRHS165*crRHS63 + crRHS166*crRHS35 + crRHS166*crRHS47 + crRHS166*crRHS63 + crRHS167*crRHS35 + crRHS167*crRHS47 + crRHS167*crRHS63 + crRHS168*crRHS35 + crRHS168*crRHS47 + crRHS168*crRHS63 + crRHS169*crRHS35 + crRHS169*crRHS47 + crRHS169*crRHS63 + crRHS170*crRHS35 + crRHS170*crRHS47 + crRHS170*crRHS63 + crRHS171*crRHS35 + crRHS171*crRHS47 + crRHS171*crRHS63 + crRHS172*crRHS35 + crRHS172*crRHS47 + crRHS172*crRHS63 + crRHS173*crRHS35 + crRHS173*crRHS47 + crRHS173*crRHS63 + crRHS174*crRHS35 + crRHS174*crRHS47 + crRHS174*crRHS63 + crRHS175*crRHS49 + crRHS176*crRHS49 + crRHS177*crRHS49 + crRHS178*crRHS49 + crRHS179*crRHS49 + crRHS180*crRHS49 + crRHS181*crRHS49 + crRHS182*crRHS49 + crRHS183*crRHS49 + crRHS184*crRHS49 + crRHS185*crRHS186 + crRHS185*crRHS187 + crRHS185*crRHS188 + crRHS185*crRHS189 + crRHS185*crRHS190 + crRHS185*crRHS191 + crRHS185*crRHS192 + crRHS185*crRHS193 + crRHS185*crRHS194 + crRHS185*crRHS195 + crRHS186*crRHS51 + crRHS187*crRHS51 + crRHS188*crRHS51 + crRHS189*crRHS51 + crRHS190*crRHS51 + crRHS191*crRHS51 + crRHS192*crRHS51 + crRHS193*crRHS51 + crRHS194*crRHS51 + crRHS195*crRHS51 + crRHS196*crRHS50 + crRHS196*crRHS84 + crRHS196*crRHS85 + crRHS197*crRHS50 + crRHS197*crRHS84 + crRHS197*crRHS85 + crRHS198*crRHS50 + crRHS198*crRHS84 + crRHS198*crRHS85 + crRHS199*crRHS50 + crRHS199*crRHS84 + crRHS199*crRHS85 + crRHS200*crRHS50 + crRHS200*crRHS84 + crRHS200*crRHS85 + crRHS201*crRHS50 + crRHS201*crRHS84 + crRHS201*crRHS85 + crRHS202*crRHS50 + crRHS202*crRHS84 + crRHS202*crRHS85 + crRHS203*crRHS50 + crRHS203*crRHS84 + crRHS203*crRHS85 + crRHS204*crRHS50 + crRHS204*crRHS84 + crRHS204*crRHS85 + crRHS205*crRHS50 + crRHS205*crRHS84 + crRHS205*crRHS85 + crRHS206*crRHS86 + crRHS207*crRHS86 + crRHS208*crRHS86 + crRHS209*crRHS86 + crRHS210*crRHS86 + crRHS211*crRHS86 + crRHS212*crRHS86 + crRHS213*crRHS86 + crRHS214*crRHS86 + crRHS215*crRHS86 + crRHS216*crRHS51 + crRHS216*crRHS86 + crRHS216*crRHS87 + crRHS217*crRHS51 + crRHS217*crRHS86 + crRHS217*crRHS87 + crRHS218*crRHS51 + crRHS218*crRHS86 + crRHS218*crRHS87 + crRHS219*crRHS51 + crRHS219*crRHS86 + crRHS219*crRHS87 + crRHS220*crRHS51 + crRHS220*crRHS86 + crRHS220*crRHS87 + crRHS221*crRHS51 + crRHS221*crRHS86 + crRHS221*crRHS87 + crRHS222*crRHS51 + crRHS222*crRHS86 + crRHS222*crRHS87 + crRHS223*crRHS51 + crRHS223*crRHS86 + crRHS223*crRHS87 + crRHS224*crRHS51 + crRHS224*crRHS86 + crRHS224*crRHS87 + crRHS225*crRHS51 + crRHS225*crRHS86 + crRHS225*crRHS87); + const double crRHS227 = N_v[1]*crRHS90; + const double crRHS228 = rho*(DN_v(1,0)*crRHS4 + DN_v(1,1)*crRHS5 + DN_v(1,2)*crRHS6); + const double crRHS229 = N_v[2]*crRHS90; + const double crRHS230 = rho*(DN_v(2,0)*crRHS4 + DN_v(2,1)*crRHS5 + DN_v(2,2)*crRHS6); + const double crRHS231 = N_v[3]*crRHS90; + const double crRHS232 = rho*(DN_v(3,0)*crRHS4 + DN_v(3,1)*crRHS5 + DN_v(3,2)*crRHS6); + const double crRHS233 = N_v[4]*crRHS90; + const double crRHS234 = rho*(DN_v(4,0)*crRHS4 + DN_v(4,1)*crRHS5 + DN_v(4,2)*crRHS6); + const double crRHS235 = N_v[5]*crRHS90; + const double crRHS236 = rho*(DN_v(5,0)*crRHS4 + DN_v(5,1)*crRHS5 + DN_v(5,2)*crRHS6); + const double crRHS237 = N_v[6]*crRHS90; + const double crRHS238 = rho*(DN_v(6,0)*crRHS4 + DN_v(6,1)*crRHS5 + DN_v(6,2)*crRHS6); + const double crRHS239 = N_v[7]*crRHS90; + const double crRHS240 = rho*(DN_v(7,0)*crRHS4 + DN_v(7,1)*crRHS5 + DN_v(7,2)*crRHS6); + const double crRHS241 = N_v[8]*crRHS90; + const double crRHS242 = rho*(DN_v(8,0)*crRHS4 + DN_v(8,1)*crRHS5 + DN_v(8,2)*crRHS6); + const double crRHS243 = N_v[9]*crRHS90; + const double crRHS244 = rho*(DN_v(9,0)*crRHS4 + DN_v(9,1)*crRHS5 + DN_v(9,2)*crRHS6); + rRHS[0]+=-gauss_weight*(-DN_v(0,0)*crRHS0 + DN_v(0,0)*crRHS12 + DN_v(0,0)*r_stress[0] + DN_v(0,1)*r_stress[3] + DN_v(0,2)*r_stress[5] - N_v[0]*crRHS1 + N_v[0]*crRHS2 + N_v[0]*crRHS7 - crRHS89*crRHS91 - crRHS89*crRHS92); + rRHS[1]+=-gauss_weight*(DN_v(0,0)*r_stress[3] - DN_v(0,1)*crRHS0 + DN_v(0,1)*crRHS12 + DN_v(0,1)*r_stress[1] + DN_v(0,2)*r_stress[4] - N_v[0]*crRHS93 + N_v[0]*crRHS94 + N_v[0]*crRHS95 - crRHS161*crRHS91 - crRHS161*crRHS92); + rRHS[2]+=-gauss_weight*(DN_v(0,0)*r_stress[5] + DN_v(0,1)*r_stress[4] - DN_v(0,2)*crRHS0 + DN_v(0,2)*crRHS12 + DN_v(0,2)*r_stress[2] - N_v[0]*crRHS162 + N_v[0]*crRHS163 + N_v[0]*crRHS164 - crRHS226*crRHS91 - crRHS226*crRHS92); + rRHS[3]+=-gauss_weight*(-DN_v(1,0)*crRHS0 + DN_v(1,0)*crRHS12 + DN_v(1,0)*r_stress[0] + DN_v(1,1)*r_stress[3] + DN_v(1,2)*r_stress[5] - N_v[1]*crRHS1 + N_v[1]*crRHS2 + N_v[1]*crRHS7 - crRHS227*crRHS89 - crRHS228*crRHS89); + rRHS[4]+=-gauss_weight*(DN_v(1,0)*r_stress[3] - DN_v(1,1)*crRHS0 + DN_v(1,1)*crRHS12 + DN_v(1,1)*r_stress[1] + DN_v(1,2)*r_stress[4] - N_v[1]*crRHS93 + N_v[1]*crRHS94 + N_v[1]*crRHS95 - crRHS161*crRHS227 - crRHS161*crRHS228); + rRHS[5]+=-gauss_weight*(DN_v(1,0)*r_stress[5] + DN_v(1,1)*r_stress[4] - DN_v(1,2)*crRHS0 + DN_v(1,2)*crRHS12 + DN_v(1,2)*r_stress[2] - N_v[1]*crRHS162 + N_v[1]*crRHS163 + N_v[1]*crRHS164 - crRHS226*crRHS227 - crRHS226*crRHS228); + rRHS[6]+=-gauss_weight*(-DN_v(2,0)*crRHS0 + DN_v(2,0)*crRHS12 + DN_v(2,0)*r_stress[0] + DN_v(2,1)*r_stress[3] + DN_v(2,2)*r_stress[5] - N_v[2]*crRHS1 + N_v[2]*crRHS2 + N_v[2]*crRHS7 - crRHS229*crRHS89 - crRHS230*crRHS89); + rRHS[7]+=-gauss_weight*(DN_v(2,0)*r_stress[3] - DN_v(2,1)*crRHS0 + DN_v(2,1)*crRHS12 + DN_v(2,1)*r_stress[1] + DN_v(2,2)*r_stress[4] - N_v[2]*crRHS93 + N_v[2]*crRHS94 + N_v[2]*crRHS95 - crRHS161*crRHS229 - crRHS161*crRHS230); + rRHS[8]+=-gauss_weight*(DN_v(2,0)*r_stress[5] + DN_v(2,1)*r_stress[4] - DN_v(2,2)*crRHS0 + DN_v(2,2)*crRHS12 + DN_v(2,2)*r_stress[2] - N_v[2]*crRHS162 + N_v[2]*crRHS163 + N_v[2]*crRHS164 - crRHS226*crRHS229 - crRHS226*crRHS230); + rRHS[9]+=-gauss_weight*(-DN_v(3,0)*crRHS0 + DN_v(3,0)*crRHS12 + DN_v(3,0)*r_stress[0] + DN_v(3,1)*r_stress[3] + DN_v(3,2)*r_stress[5] - N_v[3]*crRHS1 + N_v[3]*crRHS2 + N_v[3]*crRHS7 - crRHS231*crRHS89 - crRHS232*crRHS89); + rRHS[10]+=-gauss_weight*(DN_v(3,0)*r_stress[3] - DN_v(3,1)*crRHS0 + DN_v(3,1)*crRHS12 + DN_v(3,1)*r_stress[1] + DN_v(3,2)*r_stress[4] - N_v[3]*crRHS93 + N_v[3]*crRHS94 + N_v[3]*crRHS95 - crRHS161*crRHS231 - crRHS161*crRHS232); + rRHS[11]+=-gauss_weight*(DN_v(3,0)*r_stress[5] + DN_v(3,1)*r_stress[4] - DN_v(3,2)*crRHS0 + DN_v(3,2)*crRHS12 + DN_v(3,2)*r_stress[2] - N_v[3]*crRHS162 + N_v[3]*crRHS163 + N_v[3]*crRHS164 - crRHS226*crRHS231 - crRHS226*crRHS232); + rRHS[12]+=-gauss_weight*(-DN_v(4,0)*crRHS0 + DN_v(4,0)*crRHS12 + DN_v(4,0)*r_stress[0] + DN_v(4,1)*r_stress[3] + DN_v(4,2)*r_stress[5] - N_v[4]*crRHS1 + N_v[4]*crRHS2 + N_v[4]*crRHS7 - crRHS233*crRHS89 - crRHS234*crRHS89); + rRHS[13]+=-gauss_weight*(DN_v(4,0)*r_stress[3] - DN_v(4,1)*crRHS0 + DN_v(4,1)*crRHS12 + DN_v(4,1)*r_stress[1] + DN_v(4,2)*r_stress[4] - N_v[4]*crRHS93 + N_v[4]*crRHS94 + N_v[4]*crRHS95 - crRHS161*crRHS233 - crRHS161*crRHS234); + rRHS[14]+=-gauss_weight*(DN_v(4,0)*r_stress[5] + DN_v(4,1)*r_stress[4] - DN_v(4,2)*crRHS0 + DN_v(4,2)*crRHS12 + DN_v(4,2)*r_stress[2] - N_v[4]*crRHS162 + N_v[4]*crRHS163 + N_v[4]*crRHS164 - crRHS226*crRHS233 - crRHS226*crRHS234); + rRHS[15]+=-gauss_weight*(-DN_v(5,0)*crRHS0 + DN_v(5,0)*crRHS12 + DN_v(5,0)*r_stress[0] + DN_v(5,1)*r_stress[3] + DN_v(5,2)*r_stress[5] - N_v[5]*crRHS1 + N_v[5]*crRHS2 + N_v[5]*crRHS7 - crRHS235*crRHS89 - crRHS236*crRHS89); + rRHS[16]+=-gauss_weight*(DN_v(5,0)*r_stress[3] - DN_v(5,1)*crRHS0 + DN_v(5,1)*crRHS12 + DN_v(5,1)*r_stress[1] + DN_v(5,2)*r_stress[4] - N_v[5]*crRHS93 + N_v[5]*crRHS94 + N_v[5]*crRHS95 - crRHS161*crRHS235 - crRHS161*crRHS236); + rRHS[17]+=-gauss_weight*(DN_v(5,0)*r_stress[5] + DN_v(5,1)*r_stress[4] - DN_v(5,2)*crRHS0 + DN_v(5,2)*crRHS12 + DN_v(5,2)*r_stress[2] - N_v[5]*crRHS162 + N_v[5]*crRHS163 + N_v[5]*crRHS164 - crRHS226*crRHS235 - crRHS226*crRHS236); + rRHS[18]+=-gauss_weight*(-DN_v(6,0)*crRHS0 + DN_v(6,0)*crRHS12 + DN_v(6,0)*r_stress[0] + DN_v(6,1)*r_stress[3] + DN_v(6,2)*r_stress[5] - N_v[6]*crRHS1 + N_v[6]*crRHS2 + N_v[6]*crRHS7 - crRHS237*crRHS89 - crRHS238*crRHS89); + rRHS[19]+=-gauss_weight*(DN_v(6,0)*r_stress[3] - DN_v(6,1)*crRHS0 + DN_v(6,1)*crRHS12 + DN_v(6,1)*r_stress[1] + DN_v(6,2)*r_stress[4] - N_v[6]*crRHS93 + N_v[6]*crRHS94 + N_v[6]*crRHS95 - crRHS161*crRHS237 - crRHS161*crRHS238); + rRHS[20]+=-gauss_weight*(DN_v(6,0)*r_stress[5] + DN_v(6,1)*r_stress[4] - DN_v(6,2)*crRHS0 + DN_v(6,2)*crRHS12 + DN_v(6,2)*r_stress[2] - N_v[6]*crRHS162 + N_v[6]*crRHS163 + N_v[6]*crRHS164 - crRHS226*crRHS237 - crRHS226*crRHS238); + rRHS[21]+=-gauss_weight*(-DN_v(7,0)*crRHS0 + DN_v(7,0)*crRHS12 + DN_v(7,0)*r_stress[0] + DN_v(7,1)*r_stress[3] + DN_v(7,2)*r_stress[5] - N_v[7]*crRHS1 + N_v[7]*crRHS2 + N_v[7]*crRHS7 - crRHS239*crRHS89 - crRHS240*crRHS89); + rRHS[22]+=-gauss_weight*(DN_v(7,0)*r_stress[3] - DN_v(7,1)*crRHS0 + DN_v(7,1)*crRHS12 + DN_v(7,1)*r_stress[1] + DN_v(7,2)*r_stress[4] - N_v[7]*crRHS93 + N_v[7]*crRHS94 + N_v[7]*crRHS95 - crRHS161*crRHS239 - crRHS161*crRHS240); + rRHS[23]+=-gauss_weight*(DN_v(7,0)*r_stress[5] + DN_v(7,1)*r_stress[4] - DN_v(7,2)*crRHS0 + DN_v(7,2)*crRHS12 + DN_v(7,2)*r_stress[2] - N_v[7]*crRHS162 + N_v[7]*crRHS163 + N_v[7]*crRHS164 - crRHS226*crRHS239 - crRHS226*crRHS240); + rRHS[24]+=-gauss_weight*(-DN_v(8,0)*crRHS0 + DN_v(8,0)*crRHS12 + DN_v(8,0)*r_stress[0] + DN_v(8,1)*r_stress[3] + DN_v(8,2)*r_stress[5] - N_v[8]*crRHS1 + N_v[8]*crRHS2 + N_v[8]*crRHS7 - crRHS241*crRHS89 - crRHS242*crRHS89); + rRHS[25]+=-gauss_weight*(DN_v(8,0)*r_stress[3] - DN_v(8,1)*crRHS0 + DN_v(8,1)*crRHS12 + DN_v(8,1)*r_stress[1] + DN_v(8,2)*r_stress[4] - N_v[8]*crRHS93 + N_v[8]*crRHS94 + N_v[8]*crRHS95 - crRHS161*crRHS241 - crRHS161*crRHS242); + rRHS[26]+=-gauss_weight*(DN_v(8,0)*r_stress[5] + DN_v(8,1)*r_stress[4] - DN_v(8,2)*crRHS0 + DN_v(8,2)*crRHS12 + DN_v(8,2)*r_stress[2] - N_v[8]*crRHS162 + N_v[8]*crRHS163 + N_v[8]*crRHS164 - crRHS226*crRHS241 - crRHS226*crRHS242); + rRHS[27]+=-gauss_weight*(-DN_v(9,0)*crRHS0 + DN_v(9,0)*crRHS12 + DN_v(9,0)*r_stress[0] + DN_v(9,1)*r_stress[3] + DN_v(9,2)*r_stress[5] - N_v[9]*crRHS1 + N_v[9]*crRHS2 + N_v[9]*crRHS7 - crRHS243*crRHS89 - crRHS244*crRHS89); + rRHS[28]+=-gauss_weight*(DN_v(9,0)*r_stress[3] - DN_v(9,1)*crRHS0 + DN_v(9,1)*crRHS12 + DN_v(9,1)*r_stress[1] + DN_v(9,2)*r_stress[4] - N_v[9]*crRHS93 + N_v[9]*crRHS94 + N_v[9]*crRHS95 - crRHS161*crRHS243 - crRHS161*crRHS244); + rRHS[29]+=-gauss_weight*(DN_v(9,0)*r_stress[5] + DN_v(9,1)*r_stress[4] - DN_v(9,2)*crRHS0 + DN_v(9,2)*crRHS12 + DN_v(9,2)*r_stress[2] - N_v[9]*crRHS162 + N_v[9]*crRHS163 + N_v[9]*crRHS164 - crRHS226*crRHS243 - crRHS226*crRHS244); + rRHS[30]+=gauss_weight*(DN_p(0,0)*crRHS89 + DN_p(0,1)*crRHS161 + DN_p(0,2)*crRHS226 - N_p[0]*crRHS10); + rRHS[31]+=gauss_weight*(DN_p(1,0)*crRHS89 + DN_p(1,1)*crRHS161 + DN_p(1,2)*crRHS226 - N_p[1]*crRHS10); + rRHS[32]+=gauss_weight*(DN_p(2,0)*crRHS89 + DN_p(2,1)*crRHS161 + DN_p(2,2)*crRHS226 - N_p[2]*crRHS10); + rRHS[33]+=gauss_weight*(DN_p(3,0)*crRHS89 + DN_p(3,1)*crRHS161 + DN_p(3,2)*crRHS226 - N_p[3]*crRHS10); + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Private serialization + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::save(Serializer& rSerializer) const +{ + KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, Element); +} + + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::load(Serializer& rSerializer) +{ + KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, Element); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Class template instantiation + +template class IncompressibleNavierStokesP2P1Continuous<2>; +template class IncompressibleNavierStokesP2P1Continuous<3>; + +} \ No newline at end of file diff --git a/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.h b/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.h new file mode 100644 index 000000000000..1fa062670a23 --- /dev/null +++ b/applications/FluidDynamicsApplication/custom_elements/incompressible_navier_stokes_p2_p1_continuous.h @@ -0,0 +1,380 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main author: Ruben Zorrilla +// + +#pragma once + +// System includes + + +// External indludes + + +// Project includes +#include "geometries/geometry.h" +#include "includes/cfd_variables.h" +#include "includes/define.h" +#include "includes/element.h" +#include "includes/serializer.h" + +// Application includes +#include "custom_elements/fluid_element.h" +#include "custom_utilities/fluid_element_utilities.h" +#include "fluid_dynamics_application_variables.h" + +namespace Kratos +{ + +///@addtogroup FluidDynamicsApplication +///@{ + +///@name Kratos Globals +///@{ + +///@} +///@name Type Definitions +///@{ + +///@} +///@name Enum's +///@{ + +///@} +///@name Functions +///@{ + +///@} +///@name Kratos Classes +///@{ + +template< unsigned int TDim > +class IncompressibleNavierStokesP2P1Continuous : public Element +{ +public: + ///@name Type Definitions + ///@{ + + static constexpr std::size_t StrainSize = 3*(TDim-1); + + static constexpr std::size_t VelocityNumNodes = TDim == 2 ? 6 : 10; + + static constexpr std::size_t PressureNumNodes = TDim == 2 ? 3 : 4; + + static constexpr std::size_t LocalSize = VelocityNumNodes*TDim + PressureNumNodes; + + static constexpr IntegrationMethod IntegrationMethod = GeometryData::IntegrationMethod::GI_GAUSS_4; + + KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(IncompressibleNavierStokesP2P1Continuous); + + using BaseType = Element; + + using NodeType = BaseType::NodeType; + + using GeometryType = BaseType::GeometryType; + + using NodesArrayType = BaseType::NodesArrayType; + + using VectorType = BaseType::VectorType; + + using MatrixType = BaseType::MatrixType; + + using IndexType = BaseType::IndexType; + + using SizeType = BaseType::SizeType; + + using EquationIdVectorType = BaseType::EquationIdVectorType; + + using DofsVectorType = BaseType::DofsVectorType; + + using DofsArrayType = BaseType::DofsArrayType; + + struct ElementDataContainer + { + // Gauss point kinematics + array_1d N_v; + BoundedMatrix DN_v; + GeometryType::ShapeFunctionsSecondDerivativesType DDN_v; + + array_1d N_p; + BoundedMatrix DN_p; + + // Nodal values + array_1d Pressure; + BoundedMatrix Velocity; + BoundedMatrix VelocityOld1; + BoundedMatrix VelocityOld2; + BoundedMatrix MeshVelocity; + BoundedMatrix BodyForce; + + // Material response variables + Vector StrainRate = ZeroVector(StrainSize); + Vector ShearStress = ZeroVector(StrainSize); + Matrix ConstitutiveMatrix = ZeroMatrix(StrainSize, StrainSize); + + // Auxiliary values + double BDF0; + double BDF1; + double BDF2; + double Weight; + double DeltaTime; + + // Stabilization values + double StabC1; + double StabC2; + double DynamicTau; + double ElementSize; + + // Material parameters + double Density; + double EffectiveViscosity; + }; + + ///@} + ///@name Life Cycle + ///@{ + + //Constructors. + + /// Default constuctor. + /** + * @param NewId Index number of the new element (optional) + */ + IncompressibleNavierStokesP2P1Continuous(IndexType NewId = 0); + + /// Constructor using an array of nodes. + /** + * @param NewId Index of the new element + * @param ThisNodes An array containing the nodes of the new element + */ + IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + const NodesArrayType& ThisNodes); + + /// Constructor using a geometry object. + /** + * @param NewId Index of the new element + * @param pGeometry Pointer to a geometry object + */ + IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry); + + /// Constuctor using geometry and properties. + /** + * @param NewId Index of the new element + * @param pGeometry Pointer to a geometry object + * @param pProperties Pointer to the element's properties + */ + IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry, + Properties::Pointer pProperties); + + /// Destructor. + virtual ~IncompressibleNavierStokesP2P1Continuous(); + + /// Copy constructor. + IncompressibleNavierStokesP2P1Continuous(IncompressibleNavierStokesP2P1Continuous const &rOther) = delete; + + ///@} + ///@name Operators + ///@{ + + /// Assignment operator. + IncompressibleNavierStokesP2P1Continuous &operator=(IncompressibleNavierStokesP2P1Continuous const &rOther) = delete; + + ///@} + ///@name Operations + ///@{ + + Element::Pointer Create( + IndexType NewId, + NodesArrayType const& ThisNodes, + Properties::Pointer pProperties) const override; + + Element::Pointer Create( + IndexType NewId, + GeometryType::Pointer pGeom, + Properties::Pointer pProperties) const override; + + void Initialize(const ProcessInfo &rCurrentProcessInfo) override; + + void EquationIdVector( + EquationIdVectorType &rResult, + const ProcessInfo &rCurrentProcessInfo) const override; + + void GetDofList( + DofsVectorType &rElementalDofList, + const ProcessInfo &rCurrentProcessInfo) const override; + + void CalculateLocalSystem( + MatrixType &rLeftHandSideMatrix, + VectorType &rRightHandSideVector, + const ProcessInfo &rCurrentProcessInfo) override; + + ///@} + ///@name Inquiry + ///@{ + + int Check(const ProcessInfo &rCurrentProcessInfo) const override; + + ///@} + ///@name Input and output + ///@{ + + const Parameters GetSpecifications() const override; + + /// Turn back information as a string. + std::string Info() const override; + + /// Print information about this object. + void PrintInfo(std::ostream& rOStream) const override; + + ///@} +private: + ///@name Static Member Variables + ///@{ + + + ///@} + ///@name Member Variables + ///@{ + + /// Pointer to the viscous constitutive model + ConstitutiveLaw::Pointer mpConstitutiveLaw = nullptr; + + ///@} + ///@name Serialization + ///@{ + + friend class Serializer; + + void save(Serializer& rSerializer) const override; + + void load(Serializer& rSerializer) override; + + ///@} + ///@name Private Operators + ///@{ + + + ///@} + ///@name Private Operations + ///@{ + + /** + * @brief Set the element data container + * This method accesses the database and fills the provided data container + * @param rProcessInfo Reference to the current ProcessInfo container + * @param rElementData Reference to the data container to be filled + */ + void SetElementData( + const ProcessInfo& rProcessInfo, + ElementDataContainer& rElementData); + + /** + * @brief Calculate the kinematics + * This method calculates the current element kinematics + * @param rGaussWeights Integration points weights + * @param rVelocityN Velocity shape functions at the integration points + * @param rPressureN Pressure shape functions at the integrationo points + * @param rVelocityDNDX Velocity shape functions derivatives at the integration points + * @param rPressureDNDX Pressure shape functions derivatives at the integration points + * @param rVelocityDDNDDX Velocity shape functions second derivatives at the integration points + */ + void CalculateKinematics( + Vector& rGaussWeights, + Matrix& rVelocityN, + Matrix& rPressureN, + GeometryType::ShapeFunctionsGradientsType& rVelocityDNDX, + GeometryType::ShapeFunctionsGradientsType& rPressureDNDX, + DenseVector& rVelocityDDNDDX); + + /** + * @brief Calculates the strain rate + * This method calculates the current element strain rate and stores it in the provided data container + * @param rData Reference to the data container + */ + void CalculateStrainRate(ElementDataContainer& rData); + + /** + * @brief Adds the current Gauss point contribution to LHS + * This function adds the current Gauss point contribution to the provided Left Hand Side (LHS) matrix + * @param rData Reference to the data container from which the contribution is computed + * @param rLHS Reference to the LHS matrix + */ + void AddGaussPointLeftHandSideContribution( + const ElementDataContainer& rData, + MatrixType& rLHS); + + /** + * @brief Adds the current Gauss point contribution to RHS + * This function adds the current Gauss point contribution to the provided Right Hand Side (RHS) vector + * @param rData Reference to the data container from which the contribution is computed + * @param rRHS Reference to the RHS vector + */ + void AddGaussPointRightHandSideContribution( + const ElementDataContainer& rData, + VectorType& rRHS); + + ///@} + ///@name Private Access + ///@{ + + + ///@} + ///@name Private Inquiry + ///@{ + + + ///@} + ///@name Un accessible methods + ///@{ + + + ///@} +}; // Class IncompressibleNavierStokesP2P1Continuous + +///@} +///@name Type Definitions +///@{ + + +///@} +///@name Input and output +///@{ + +/// input stream function +template< unsigned int TDim > +inline std::istream& operator >>( + std::istream& rIStream, + IncompressibleNavierStokesP2P1Continuous& rThis) +{ + return rIStream; +} + +/// output stream function +template< unsigned int TDim > +inline std::ostream& operator <<( + std::ostream& rOStream, + const IncompressibleNavierStokesP2P1Continuous& rThis) +{ + rThis.PrintInfo(rOStream); + rOStream << std::endl; + rThis.PrintData(rOStream); + + return rOStream; +} + +///@} +///@} // Fluid Dynamics Application group + +} // namespace Kratos. diff --git a/applications/FluidDynamicsApplication/custom_python/add_custom_utilities_to_python.cpp b/applications/FluidDynamicsApplication/custom_python/add_custom_utilities_to_python.cpp index cd183fbde942..e1bc9c198a85 100644 --- a/applications/FluidDynamicsApplication/custom_python/add_custom_utilities_to_python.cpp +++ b/applications/FluidDynamicsApplication/custom_python/add_custom_utilities_to_python.cpp @@ -188,6 +188,7 @@ void AddCustomUtilitiesToPython(pybind11::module& m) .def_static("MapVelocityFromSkinToVolumeRBF", &FluidAuxiliaryUtilities::MapVelocityFromSkinToVolumeRBF) .def_static("FindMaximumEdgeLength", [](ModelPart& rModelPart){return FluidAuxiliaryUtilities::FindMaximumEdgeLength(rModelPart);}) .def_static("FindMaximumEdgeLength", [](ModelPart& rModelPart, const bool CalculateNodalNeighbours){return FluidAuxiliaryUtilities::FindMaximumEdgeLength(rModelPart, CalculateNodalNeighbours);}) + .def_static("PostprocessP2P1ContinuousPressure", [](ModelPart& rModelPart){return FluidAuxiliaryUtilities::PostprocessP2P1ContinuousPressure(rModelPart);}) ; py::class_(m, "FluidTestUtilities") diff --git a/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.cpp b/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.cpp index c093301994be..d4a647953ffa 100644 --- a/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.cpp +++ b/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.cpp @@ -25,6 +25,7 @@ #include "utilities/reduction_utilities.h" #include "spatial_containers/bins_dynamic.h" #include "utilities/rbf_shape_functions_utility.h" +#include "utilities/variable_utils.h" // Application includes #include "fluid_auxiliary_utilities.h" @@ -476,4 +477,39 @@ double FluidAuxiliaryUtilities::FindMaximumEdgeLength( return l_max; } +void FluidAuxiliaryUtilities::PostprocessP2P1ContinuousPressure(ModelPart& rModelPart) +{ + // Reset VISITED flag to indicate the already postprocessed nodes + VariableUtils().SetFlag(VISITED, false, rModelPart.Nodes()); + + // Loop the P2P1 elements to postprocess the pressure in edge midpoint nodes + // Note that there is no need to do MPI synchronization as we are updating the ghost nodes too + if (rModelPart.GetCommunicator().LocalMesh().NumberOfElements() != 0) { + // Check DOMAIN_SIZE + KRATOS_ERROR_IF_NOT(rModelPart.GetProcessInfo().Has(DOMAIN_SIZE)) + << "DOMAIN_SIZE cannot be found in '" << rModelPart.FullName() << "' ProcessInfo container."<< std::endl; + // Loop the elements to assign the edge midpoint nodes PRESSURE + if (rModelPart.GetProcessInfo()[DOMAIN_SIZE] == 2) { + block_for_each(rModelPart.Elements(), [](auto& rElement){ + auto& r_geometry = rElement.GetGeometry(); + KRATOS_ERROR_IF_NOT(r_geometry.GetGeometryType() == GeometryData::KratosGeometryType::Kratos_Triangle2D6); + PostprocessP2P1NodePressure(r_geometry, 3, 0, 1); + PostprocessP2P1NodePressure(r_geometry, 4, 1, 2); + PostprocessP2P1NodePressure(r_geometry, 5, 0, 2); + }); + } else { + block_for_each(rModelPart.Elements(), [](auto& rElement){ + auto& r_geometry = rElement.GetGeometry(); + KRATOS_ERROR_IF_NOT(r_geometry.GetGeometryType() == GeometryData::KratosGeometryType::Kratos_Tetrahedra3D10); + PostprocessP2P1NodePressure(r_geometry, 4, 0, 1); + PostprocessP2P1NodePressure(r_geometry, 5, 1, 2); + PostprocessP2P1NodePressure(r_geometry, 6, 0, 2); + PostprocessP2P1NodePressure(r_geometry, 7, 0, 3); + PostprocessP2P1NodePressure(r_geometry, 8, 1, 3); + PostprocessP2P1NodePressure(r_geometry, 9, 2, 3); + }); + } + } +} + } // namespace Kratos diff --git a/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.h b/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.h index 1d5ad19fc092..a13fcfd217ac 100644 --- a/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.h +++ b/applications/FluidDynamicsApplication/custom_utilities/fluid_auxiliary_utilities.h @@ -11,8 +11,7 @@ // Suneth Warnakulasuriya // -#if !defined(KRATOS_FLUID_AUXILIARY_UTILITIES_H) -#define KRATOS_FLUID_AUXILIARY_UTILITIES_H +#pragma once // System includes @@ -230,6 +229,15 @@ class KRATOS_API(FLUID_DYNAMICS_APPLICATION) FluidAuxiliaryUtilities ModelPart& rModelPart, const bool CalculateNodalNeighbours = true); + /** + * @brief Postprocess the midpoint nodes pressure in P2P1 elements + * This function takes the edges' midpoint nodes in P2P1 elements and postprocess the pressure, which + * is assumed to be stored in PRESSURE historical variable, from the edges' endpoint values. + * Note that the nodal flag VISITED is used to mark the nodes which pressure has been already set. + * @param rModelPart The model part to which the pressure is to be postprocessed + */ + static void PostprocessP2P1ContinuousPressure(ModelPart& rModelPart); + ///@} private: @@ -300,10 +308,33 @@ class KRATOS_API(FLUID_DYNAMICS_APPLICATION) FluidAuxiliaryUtilities std::vector>& rNormals, Vector& rWeights); + /** + * @brief Auxilary function to postprocess one P2P1 edge pressure + * This function postprocesses the PRESSURE in a P2P1 element edge midpoint. + * Once the pressure value is set, the node is marked as VISITED. + * @param rGeometry Reference to current element geometry + * @param PostNodeLocalId Local id of the node to which the pressure is to be set + * @param EdgeNodeLocalIdI Local id of the i-node of the edge to which previous node belongs + * @param EdgeNodeLocalIdJ Local id of the j-node of the edge to which previous node belongs + */ + static void PostprocessP2P1NodePressure( + GeometryType& rGeometry, + const std::size_t PostNodeLocalId, + const std::size_t EdgeNodeLocalIdI, + const std::size_t EdgeNodeLocalIdJ) + { + if (rGeometry[PostNodeLocalId].IsNot(VISITED)) { + rGeometry[PostNodeLocalId].SetLock(); + const double p_i = rGeometry[EdgeNodeLocalIdI].FastGetSolutionStepValue(PRESSURE); + const double p_j = rGeometry[EdgeNodeLocalIdJ].FastGetSolutionStepValue(PRESSURE); + rGeometry[PostNodeLocalId].FastGetSolutionStepValue(PRESSURE) = 0.5 * (p_i + p_j); + rGeometry[PostNodeLocalId].Set(VISITED, true); + rGeometry[PostNodeLocalId].UnSetLock(); + } + } + }; ///@} } // namespace Kratos - -#endif // KRATOS_FLUID_AUXILIARY_UTILITIES_H diff --git a/applications/FluidDynamicsApplication/fluid_dynamics_application.cpp b/applications/FluidDynamicsApplication/fluid_dynamics_application.cpp index c9d524397b79..4293b9c56bab 100644 --- a/applications/FluidDynamicsApplication/fluid_dynamics_application.cpp +++ b/applications/FluidDynamicsApplication/fluid_dynamics_application.cpp @@ -136,6 +136,9 @@ KratosFluidDynamicsApplication::KratosFluidDynamicsApplication(): mNavierStokesLinearLogWallCondition3D(0, Element::GeometryType::Pointer(new Triangle3D3(Element::GeometryType::PointsArrayType(3)))), mNavierStokesNavierSlipWallCondition2D(0, Element::GeometryType::Pointer(new Line2D2(Element::GeometryType::PointsArrayType(2)))), mNavierStokesNavierSlipWallCondition3D(0, Element::GeometryType::Pointer(new Triangle3D3(Element::GeometryType::PointsArrayType(3)))), + // Incompressible Navier-Stokes div-stable wall condition + mNavierStokesP2P1ContinuousWallCondition2D(0, Element::GeometryType::Pointer(new Line2D3(Element::GeometryType::PointsArrayType(3)))), + mNavierStokesP2P1ContinuousWallCondition3D(0, Element::GeometryType::Pointer(new Triangle3D6(Element::GeometryType::PointsArrayType(6)))), // Embedded Navier-Stokes symbolic elements mEmbeddedNavierStokes2D(0, Element::GeometryType::Pointer(new Triangle2D3(Element::GeometryType::PointsArrayType(3)))), mEmbeddedNavierStokes3D(0, Element::GeometryType::Pointer(new Tetrahedra3D4(Element::GeometryType::PointsArrayType(4)))), @@ -155,6 +158,9 @@ KratosFluidDynamicsApplication::KratosFluidDynamicsApplication(): mTwoFluidNavierStokesAlphaMethod3D4N(0, Element::GeometryType::Pointer(new Tetrahedra3D4(Element::GeometryType::PointsArrayType(4)))), mTwoFluidNavierStokesWallCondition2D(0, Element::GeometryType::Pointer(new Line2D2(Element::GeometryType::PointsArrayType(2)))), mTwoFluidNavierStokesWallCondition3D(0, Element::GeometryType::Pointer(new Triangle3D3(Element::GeometryType::PointsArrayType(3)))), + // Incompressbile Navier-Stokes div-stable elements + mIncompressibleNavierStokesP2P1Continuous2D6N(0, Element::GeometryType::Pointer(new Triangle2D6(Element::GeometryType::PointsArrayType(6)))), + mIncompressibleNavierStokesP2P1Continuous3D10N(0, Element::GeometryType::Pointer(new Tetrahedra3D10(Element::GeometryType::PointsArrayType(10)))), // Fluid adjoint elements mVMSAdjointElement2D(0,Element::GeometryType::Pointer(new Triangle2D3(Element::GeometryType::PointsArrayType(3)))), mVMSAdjointElement3D(0,Element::GeometryType::Pointer(new Tetrahedra3D4(Element::GeometryType::PointsArrayType(4)))), @@ -386,6 +392,10 @@ void KratosFluidDynamicsApplication::Register() { KRATOS_REGISTER_ELEMENT("CompressibleNavierStokesExplicit2D4N",mCompressibleNavierStokesExplicit2D4N); KRATOS_REGISTER_ELEMENT("CompressibleNavierStokesExplicit3D4N",mCompressibleNavierStokesExplicit3D4N); + // Incompressbile Navier-Stokes div-stable elements + KRATOS_REGISTER_ELEMENT("IncompressibleNavierStokesP2P1Continuous2D6N",mIncompressibleNavierStokesP2P1Continuous2D6N); + KRATOS_REGISTER_ELEMENT("IncompressibleNavierStokesP2P1Continuous3D10N",mIncompressibleNavierStokesP2P1Continuous3D10N); + // Adjoint elements KRATOS_REGISTER_ELEMENT("VMSAdjointElement2D", mVMSAdjointElement2D); // old naming convention KRATOS_REGISTER_ELEMENT("VMSAdjointElement3D", mVMSAdjointElement3D); // old naming convention @@ -417,6 +427,8 @@ void KratosFluidDynamicsApplication::Register() { KRATOS_REGISTER_CONDITION("NavierStokesLinearLogWallCondition3D3N", mNavierStokesLinearLogWallCondition3D); KRATOS_REGISTER_CONDITION("NavierStokesNavierSlipWallCondition2D2N", mNavierStokesNavierSlipWallCondition2D); KRATOS_REGISTER_CONDITION("NavierStokesNavierSlipWallCondition3D3N", mNavierStokesNavierSlipWallCondition3D); + KRATOS_REGISTER_CONDITION("NavierStokesP2P1ContinuousWallCondition2D3N", mNavierStokesP2P1ContinuousWallCondition2D); + KRATOS_REGISTER_CONDITION("NavierStokesP2P1ContinuousWallCondition3D6N", mNavierStokesP2P1ContinuousWallCondition3D); KRATOS_REGISTER_CONDITION("TwoFluidNavierStokesWallCondition2D2N", mTwoFluidNavierStokesWallCondition2D); KRATOS_REGISTER_CONDITION("TwoFluidNavierStokesWallCondition3D3N", mTwoFluidNavierStokesWallCondition3D); KRATOS_REGISTER_CONDITION("EmbeddedAusasNavierStokesWallCondition2D2N", mEmbeddedAusasNavierStokesWallCondition2D); diff --git a/applications/FluidDynamicsApplication/fluid_dynamics_application.h b/applications/FluidDynamicsApplication/fluid_dynamics_application.h index 3ffcc70a6b4c..bc0dbb101a61 100644 --- a/applications/FluidDynamicsApplication/fluid_dynamics_application.h +++ b/applications/FluidDynamicsApplication/fluid_dynamics_application.h @@ -55,6 +55,8 @@ #include "custom_elements/fractional_step.h" #include "custom_elements/fractional_step_discontinuous.h" #include "custom_elements/spalart_allmaras.h" +#include "custom_elements/incompressible_navier_stokes_p2_p1_continuous.h" + #include "custom_conditions/wall_condition.h" #include "custom_conditions/fs_werner_wengle_wall_condition.h" #include "custom_conditions/fs_generalized_wall_condition.h" @@ -64,6 +66,7 @@ #include "custom_conditions/two_fluid_navier_stokes_wall_condition.h" #include "custom_conditions/fs_periodic_condition.h" #include "custom_conditions/navier_stokes_wall_condition.h" +#include "custom_conditions/navier_stokes_p2_p1_continuous_wall_condition.h" #include "custom_conditions/embedded_ausas_navier_stokes_wall_condition.h" #include "custom_elements/dpg_vms.h" @@ -424,6 +427,10 @@ class KRATOS_API(FLUID_DYNAMICS_APPLICATION) KratosFluidDynamicsApplication : pu const NavierStokesWallCondition<2,2,NavierSlipWallLaw<2,2>> mNavierStokesNavierSlipWallCondition2D; const NavierStokesWallCondition<3,3,NavierSlipWallLaw<3,3>> mNavierStokesNavierSlipWallCondition3D; + /// Incompressible Navier-Stokes div-stable wall condition + const NavierStokesP2P1ContinuousWallCondition<2> mNavierStokesP2P1ContinuousWallCondition2D; + const NavierStokesP2P1ContinuousWallCondition<3> mNavierStokesP2P1ContinuousWallCondition3D; + /// Embedded Navier-Stokes symbolic element const EmbeddedNavierStokes<2> mEmbeddedNavierStokes2D; const EmbeddedNavierStokes<3> mEmbeddedNavierStokes3D; @@ -447,6 +454,10 @@ class KRATOS_API(FLUID_DYNAMICS_APPLICATION) KratosFluidDynamicsApplication : pu const TwoFluidNavierStokesWallCondition<2,2> mTwoFluidNavierStokesWallCondition2D; const TwoFluidNavierStokesWallCondition<3,3> mTwoFluidNavierStokesWallCondition3D; + /// Incompressible Navier-Stokes div-stable element + const IncompressibleNavierStokesP2P1Continuous<2> mIncompressibleNavierStokesP2P1Continuous2D6N; + const IncompressibleNavierStokesP2P1Continuous<3> mIncompressibleNavierStokesP2P1Continuous3D10N; + /// Fluid constitutive laws const Bingham3DLaw mBingham3DLaw; const Euler2DLaw mEuler2DLaw; diff --git a/applications/FluidDynamicsApplication/python_scripts/navier_stokes_monolithic_solver.py b/applications/FluidDynamicsApplication/python_scripts/navier_stokes_monolithic_solver.py index d6efe3cd57c9..cad304333928 100755 --- a/applications/FluidDynamicsApplication/python_scripts/navier_stokes_monolithic_solver.py +++ b/applications/FluidDynamicsApplication/python_scripts/navier_stokes_monolithic_solver.py @@ -38,9 +38,18 @@ def __init__(self,settings): self._SetUpWeaklyCompressible(settings) elif formulation == "axisymmetric_navier_stokes": self._SetUpAxisymmetricNavierStokes(settings) + elif formulation == "p2p1": + self._SetUpP2P1(settings) + else: + formulation_list = ["qsvms", "dvms", "fic", "weakly_compressible", "axisymmetric_navier_stokes", "p2p1"] + err_msg = f"Wrong \'element_type\' : \'{formulation}\' provided. Available options are:\n" + for elem in formulation_list: + err_msg += f"\t- {elem}\n" + # raise RuntimeError(err_msg) #TODO: Turn this into an error once the derived solvers handle this properly + KratosMultiphysics.Logger.PrintWarning("NavierStokesMonolithicSolver", err_msg) else: print(settings) - raise RuntimeError("Argument \'element_type\' not found in stabilization settings.") + raise RuntimeError("Argument \'element_type\' not found in formulation settings.") def SetProcessInfo(self,model_part): for variable,value in self.process_data.items(): @@ -185,6 +194,20 @@ def _SetUpAxisymmetricNavierStokes(self,settings): self.process_data[KratosMultiphysics.DYNAMIC_TAU] = settings["dynamic_tau"].GetDouble() + def _SetUpP2P1(self,settings): + default_settings = KratosMultiphysics.Parameters(r"""{ + "element_type": "p2p1", + "dynamic_tau": 1.0 + }""") + settings.ValidateAndAssignDefaults(default_settings) + + self.element_name = "IncompressibleNavierStokesP2P1Continuous" + self.condition_name = "NavierStokesP2P1ContinuousWallCondition" + self.element_integrates_in_time = True + self.element_has_nodal_properties = False + + self.process_data[KratosMultiphysics.DYNAMIC_TAU] = settings["dynamic_tau"].GetDouble() + def CreateSolver(model, custom_settings): return NavierStokesMonolithicSolver(model, custom_settings) @@ -307,6 +330,18 @@ def InitializeSolutionStep(self): # Perform the solver InitializeSolutionStep self._GetSolutionStrategy().InitializeSolutionStep() + def SolveSolutionStep(self): + # Call the base fluid solver to solve current time step + is_converged = super().SolveSolutionStep() + + # If the P2-P1 element is used, postprocess the pressure in the quadratic nodes for the visualization + # Note that this must be done in here (not in the FinalizeSolutionStep) in case the SolveSolutionStep + # is called in a non-linear outer loop (e.g. from the FSI or the CHT solvers) + if self.element_name == "IncompressibleNavierStokesP2P1Continuous": + KratosCFD.FluidAuxiliaryUtilities.PostprocessP2P1ContinuousPressure(self.GetComputingModelPart()) + + return is_converged + def _SetFormulation(self): self.formulation = StabilizedFormulation(self.settings["formulation"]) self.element_name = self.formulation.element_name diff --git a/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/README.md b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/README.md new file mode 100644 index 000000000000..3f7609575b13 --- /dev/null +++ b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/README.md @@ -0,0 +1,16 @@ +# Incompressible Navier-Stokes P2/P1 continuous automatic differentiation + +## ELEMENT DESCRIPTION: +Current directory contains the required files for the Automatic Differenctiation (AD) of the _"incompressible_navier_stokes_p2_p1_continuous"_ element of the FluidDynamicsApplication. This element implements an **incompressible Navier-Stokes** formulation with a P2/P1 continuous (Taylor-Hood) inf-sup stable interpolation pair for both **2D** and **3D** cases. Quasi-static Algebraic Sub-Grid Scales (ASGS) are used for the stabilization of the convection. + +## SYMBOLIC GENERATOR SETTINGS: +* Dimension to compute: this symbolic generator is valid for both **2D** and **3D** cases. The element has been implemented using a template argument for the problem dimension, so it is advised to set the _dim_to_compute_ flag as "_Both_". In this case the generated .cpp file will contain both **2D** and **3D** implementations. +* Linearisation settings: "_FullNR_" considers the convective velocity as _"v-vmesh"_, implying that _v_ is taken into account in the differenctiation of the **LHS** and **RHS**. On the contrary "_Picard_" option (_a.k.a. QuasiNR_) defines the convective velocity as "a", so it is considered as a constant in the differenctiation of the **LHS** and **RHS**. +* Add pressure subscale: if set to _True_ the pressure subscale component is added to the momentum equation to effectively get the div-div stabilization term. Though it is not required, this term is known to greatly improve the solution in presence of inf-sup stable approximants (see a detailed discussion in [here](https://doi.org/10.1016/j.cma.2016.02.026)). + +## INSTRUCTIONS +Run: +~~~py +python generate_incompressible_navier_stokes_p2_p1_continuous_element.py +~~~ +Then, a file "_incompressible_navier_stokes_p2_p1_continuous.cpp_" is automatically generated. Such file muest be moved to the "_custom_elements_" folder of the **FluidDynamicsApplication**. The corresponding header file ("incompressible_navier_stokes_p2_p1_continuous.h") is already stored in there. diff --git a/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/generate_incompressible_navier_stokes_p2_p1_continuous_element.py b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/generate_incompressible_navier_stokes_p2_p1_continuous_element.py new file mode 100644 index 000000000000..2ee7e48c906f --- /dev/null +++ b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/generate_incompressible_navier_stokes_p2_p1_continuous_element.py @@ -0,0 +1,206 @@ +import sympy +from KratosMultiphysics import * +from KratosMultiphysics.sympy_fe_utilities import * + +## Symbolic generation settings +mode = "c" +do_simplifications = False +dim_to_compute = "Both" # Spatial dimensions to compute. Options: "2D","3D","Both" +linearisation = "Picard" # Convective term linearisation type +add_pressure_subscale = True # Specifies if the pressure subscale is added to the momentum equation to get the div(w)div(v) term + +output_filename = "incompressible_navier_stokes_p2_p1_continuous.cpp" +template_filename = "incompressible_navier_stokes_p2_p1_continuous_cpp_template.cpp" + +info_msg = "\n" +info_msg += "Element generator settings:\n" +info_msg += f"\t - Dimension: {dim_to_compute}\n" +info_msg += f"\t - Linearisation: {linearisation}\n" +info_msg += f"\t - Pressure subscale: {add_pressure_subscale}\n" +print(info_msg) + +if dim_to_compute == "2D": + dim_vector = [2] + v_nodes_vector = [6] # tria + p_nodes_vector = [3] # tria +elif dim_to_compute == "3D": + dim_vector = [3] + v_nodes_vector = [10] # tet + p_nodes_vector = [4] # tet +elif dim_to_compute == "Both": + dim_vector = [2, 3] + v_nodes_vector = [6, 10] # tria, tet + p_nodes_vector = [3, 4] # tria, tet + +## Initialize the outstring to be filled with the template .cpp file +print(f"Reading template file \'{template_filename}'\n") +templatefile = open(template_filename) +outstring = templatefile.read() + +for dim, v_n_nodes, p_n_nodes in zip(dim_vector, v_nodes_vector, p_nodes_vector): + + if dim == 2: + strain_size = 3 + elif dim == 3: + strain_size = 6 + + ## Kinematics symbols definition + N_v, DN_v, DDN_v = DefineShapeFunctions(v_n_nodes, dim, impose_partion_of_unity=False, shape_functions_name='N_v', first_derivatives_name='DN_v', second_derivatives_name='DDN_v') + N_p, DN_p = DefineShapeFunctions(p_n_nodes, dim, impose_partion_of_unity=False, shape_functions_name='N_p', first_derivatives_name='DN_p') + + ## Unknown fields definition + v = DefineMatrix('r_v', v_n_nodes, dim) # Current step velocity (v(i,j) refers to velocity of node i component j) + vn = DefineMatrix('r_vn', v_n_nodes, dim) # Previous step velocity + vnn = DefineMatrix('r_vnn', v_n_nodes, dim) # 2 previous step velocity + p = DefineVector('r_p', p_n_nodes) # Pressure + + ## Fluid properties + mu = sympy.Symbol('mu', positive = True) # Dynamic viscosity + rho = sympy.Symbol('rho', positive = True) # Density + + ## Test functions definition + w = DefineMatrix('w', v_n_nodes, dim) # Velocity field test function + q = DefineVector('q', p_n_nodes) # Pressure field test function + + ## Other data definitions + f = DefineMatrix('r_f',v_n_nodes,dim) # Forcing term + + ## Constitutive matrix definition + C = DefineSymmetricMatrix('C',strain_size,strain_size) + + ## Stress vector definition + stress = DefineVector('r_stress',strain_size) + + ## Other simbols definition + h = sympy.Symbol('h', positive = True) # Element characteristic size + stab_c1 = sympy.Symbol('stab_c1', positive = True) # Stabilization first constant + stab_c2 = sympy.Symbol('stab_c2', positive = True) # Stabilization second constant + dyn_tau = sympy.Symbol('dyn_tau', positive = True) # Stabilization dynamic tau + dt = sympy.Symbol('rData.DeltaTime', positive = True) # Time increment + gauss_weight = sympy.Symbol('gauss_weight', positive = True) # Integration point weight + + ## Backward differences coefficients + bdf0 = sympy.Symbol('rData.BDF0') + bdf1 = sympy.Symbol('rData.BDF1') + bdf2 = sympy.Symbol('rData.BDF2') + + ## Convective velocity definition + if linearisation == "Picard": + vconv = DefineMatrix('vconv',v_n_nodes,dim) # Convective velocity defined a symbol + elif linearisation == "FullNR": + vmesh = DefineMatrix('r_vmesh',v_n_nodes,dim) # Mesh velocity + vconv = v - vmesh # Convective velocity defined as a velocity dependent variable + else: + raise Exception(f"Wrong linearisation \'{linearisation}\' selected. Available options are \'Picard\' and \'FullNR\'.") + vconv_gauss = vconv.transpose()*N_v + + ## Compute the rest of magnitudes at the Gauss points + accel_gauss = (bdf0*v + bdf1*vn + bdf2*vnn).transpose()*N_v + + ## Data interpolation to the Gauss points + f_gauss = f.transpose()*N_v + + v_gauss = v.transpose()*N_v + p_gauss = p.transpose()*N_p + + w_gauss = w.transpose()*N_v + q_gauss = q.transpose()*N_p + + ## Gradients computation (fluid dynamics gradient) + grad_w = DfjDxi(DN_v, w) + grad_q = DfjDxi(DN_p, q) + + grad_v = DfjDxi(DN_v,v) + grad_p = DfjDxi(DN_p, p) + + div_w = div(DN_v,w) + div_v = div(DN_v,v) + + div_vconv = div(DN_v, vconv) + + grad_sym_v = grad_sym_voigtform(DN_v,v) # Symmetric gradient of v in Voigt notation + grad_sym_w_voigt = grad_sym_voigtform(DN_v,w) # Symmetric gradient of w in Voigt notation + # Recall that the grad(w):stress contraction equals grad_sym(w)*stress in Voigt notation since the stress is a symmetric tensor. + + # Convective term definition + convective_term_gauss = vconv_gauss.transpose()*grad_v + + ## Compute galerkin functional + # Navier-Stokes functional + rv_galerkin = rho*w_gauss.transpose()*f_gauss - rho*w_gauss.transpose()*accel_gauss - grad_sym_w_voigt.transpose()*stress + div_w*p_gauss - q_gauss*div_v + rv_galerkin -= rho*w_gauss.transpose()*convective_term_gauss.transpose() + + ## Stabilization functional + stab_norm_a = 0.0 + for i in range(dim): + stab_norm_a += vconv_gauss[i]**2 + stab_norm_a = sympy.sqrt(stab_norm_a) + tau_1 = 1.0/(rho*dyn_tau/dt + stab_c2*rho*stab_norm_a/h + stab_c1*mu/h**2) # Velocity stabilization operator + tau_2 = mu + stab_c2*rho*stab_norm_a*h/stab_c1 # Pressure stabilization operator + + C_aux = ConvertVoigtMatrixToTensor(C) # Definition of the 4th order constitutive tensor from the previous definition symbols + div_stress = sympy.zeros(dim, 1) + for i in range(dim): + for j in range(dim): + for k in range(dim): + for m in range(dim): + for n in range(v_n_nodes): + div_stress[i] += 0.5*C_aux[i,j,k,m]*(DDN_v[0,n][i,m]*v[n,k] + DDN_v[0,n][i,k]*v[n,m]) + + mom_residual = rho*f_gauss - rho*accel_gauss - rho*convective_term_gauss.transpose() + div_stress - grad_p + vel_subscale = tau_1 * mom_residual + + mass_residual = - div_v + pres_subscale = tau_2 * mass_residual + + rv_stab = grad_q.transpose()*vel_subscale + rv_stab += rho*vconv_gauss.transpose()*grad_w*vel_subscale + rv_stab += rho*div_vconv*w_gauss.transpose()*vel_subscale + if add_pressure_subscale: + rv_stab += div_w * pres_subscale + + ## Define DOFs and test function vectors + n_dofs = v_n_nodes * dim + p_n_nodes + + dofs = sympy.zeros(n_dofs, 1) + testfunc = sympy.zeros(n_dofs, 1) + + # Velocity DOFs and test functions + for i in range(v_n_nodes): + for k in range(dim): + dofs[i*dim + k] = v[i,k] + testfunc[i*dim + k] = w[i,k] + + # Pressure DOFs and test functions + for i in range(p_n_nodes): + dofs[v_n_nodes*dim + i] = p[i,0] + testfunc[v_n_nodes*dim + i] = q[i,0] + + ## Compute LHS and RHS + # Add the stabilization to the Galerkin residual + functional = rv_galerkin + rv_stab + + # For the RHS computation one wants the residual of the previous iteration (residual based formulation). By this reason the stress is + # included as a symbolic variable, which is assumed to be passed as an argument from the previous iteration database. + print(f"Computing {dim}D RHS Gauss point contribution\n") + rhs = Compute_RHS(functional.copy(), testfunc, do_simplifications) + rhs_out = OutputVector_CollectingFactors(gauss_weight*rhs, "rRHS", mode, assignment_op='+=') + + # Compute LHS (RHS(residual) differenctiation w.r.t. the DOFs) + # Note that the 'stress' (symbolic variable) is substituted by 'C*grad_sym_v' for the LHS differenctiation. Otherwise the velocity terms + # within the velocity symmetryc gradient would not be considered in the differenctiation, meaning that the stress would be considered as + # a velocity independent constant in the LHS. + print(f"Computing {dim}D LHS Gauss point contribution\n") + SubstituteMatrixValue(rhs, stress, C*grad_sym_v) + lhs = Compute_LHS(rhs, testfunc, dofs, do_simplifications) # Compute the LHS (considering stress as C*(B*v) to derive w.r.t. v) + lhs_out = OutputMatrix_CollectingFactors(gauss_weight*lhs, "rLHS", mode, assignment_op='+=') + + ## Replace the computed RHS and LHS in the template outstring + outstring = outstring.replace(f"//substitute_lhs_{dim}D", lhs_out) + outstring = outstring.replace(f"//substitute_rhs_{dim}D", rhs_out) + +## Write the modified template +print(f"Writing output file \'{output_filename}\'") +out = open(output_filename,'w') +out.write(outstring) +out.close() diff --git a/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/incompressible_navier_stokes_p2_p1_continuous_cpp_template.cpp b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/incompressible_navier_stokes_p2_p1_continuous_cpp_template.cpp new file mode 100644 index 000000000000..d0dc94713c8f --- /dev/null +++ b/applications/FluidDynamicsApplication/python_scripts/symbolic_generation/incompressible_navier_stokes_p2_p1_continuous/incompressible_navier_stokes_p2_p1_continuous_cpp_template.cpp @@ -0,0 +1,615 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + +// System includes + + +// External includes + + +// Project includes +#include "utilities/element_size_calculator.h" + +// Application includes +#include "incompressible_navier_stokes_p2_p1_continuous.h" + +namespace Kratos +{ + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Life cycle + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous(IndexType NewId) + : Element(NewId) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + const NodesArrayType& ThisNodes) + : Element(NewId, ThisNodes) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry) + : Element(NewId, pGeometry) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::IncompressibleNavierStokesP2P1Continuous( + IndexType NewId, + GeometryType::Pointer pGeometry, + Properties::Pointer pProperties) + : Element(NewId, pGeometry, pProperties) +{} + +template< unsigned int TDim > +IncompressibleNavierStokesP2P1Continuous::~IncompressibleNavierStokesP2P1Continuous() +{} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public Operations + +template< unsigned int TDim > +Element::Pointer IncompressibleNavierStokesP2P1Continuous::Create( + IndexType NewId, + NodesArrayType const& ThisNodes, + Properties::Pointer pProperties) const +{ + return Kratos::make_intrusive>(NewId, this->GetGeometry().Create(ThisNodes), pProperties); +} + +template< unsigned int TDim > +Element::Pointer IncompressibleNavierStokesP2P1Continuous::Create( + IndexType NewId, + GeometryType::Pointer pGeom, + Properties::Pointer pProperties) const +{ + return Kratos::make_intrusive>(NewId, pGeom, pProperties); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::Initialize(const ProcessInfo& rCurrentProcessInfo) +{ + KRATOS_TRY; + + // If we are restarting, the constitutive law will be already defined + if (mpConstitutiveLaw == nullptr) { + const auto& r_properties = this->GetProperties(); + KRATOS_ERROR_IF_NOT(r_properties.Has(CONSTITUTIVE_LAW)) + << "In initialization of Element " << this->Info() + << ": No CONSTITUTIVE_LAW defined for property " + << r_properties.Id() << "." << std::endl; + + mpConstitutiveLaw = r_properties[CONSTITUTIVE_LAW]->Clone(); + + const auto& r_geometry = this->GetGeometry(); + const auto& r_shape_functions = r_geometry.ShapeFunctionsValues(GeometryData::IntegrationMethod::GI_GAUSS_1); + mpConstitutiveLaw->InitializeMaterial(r_properties, r_geometry, row(r_shape_functions,0)); + } + + KRATOS_CATCH(""); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::EquationIdVector( + EquationIdVectorType &rResult, + const ProcessInfo &rCurrentProcessInfo) const +{ + if (rResult.size() != LocalSize) { + rResult.resize(LocalSize, false); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_X, x_pos).EquationId(); + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Y, x_pos+1).EquationId(); + if constexpr (TDim == 3) { + rResult[local_index++] = r_geometry[i].GetDof(VELOCITY_Z, x_pos+2).EquationId(); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rResult[local_index++] = r_geometry[i].GetDof(PRESSURE, p_pos).EquationId(); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::GetDofList( + DofsVectorType &rElementalDofList, + const ProcessInfo &rCurrentProcessInfo) const +{ + if (rElementalDofList.size() != LocalSize) { + rElementalDofList.resize(LocalSize); + } + + IndexType local_index = 0; + const auto& r_geometry = this->GetGeometry(); + const IndexType x_pos = this->GetGeometry()[0].GetDofPosition(VELOCITY_X); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_X, x_pos); + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Y, x_pos+1); + if constexpr (TDim == 3) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(VELOCITY_Z, x_pos+2); + } + } + + const IndexType p_pos = this->GetGeometry()[0].GetDofPosition(PRESSURE); + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rElementalDofList[local_index++] = r_geometry[i].pGetDof(PRESSURE, p_pos); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateLocalSystem( + MatrixType& rLeftHandSideMatrix, + VectorType& rRightHandSideVector, + const ProcessInfo& rCurrentProcessInfo) +{ + // Resize and intialize output + if (rLeftHandSideMatrix.size1() != LocalSize || rLeftHandSideMatrix.size2() != LocalSize) { + rLeftHandSideMatrix.resize(LocalSize, LocalSize, false); + } + + if (rRightHandSideVector.size() != LocalSize) { + rRightHandSideVector.resize(LocalSize, false); + } + + noalias(rLeftHandSideMatrix) = ZeroMatrix(LocalSize, LocalSize); + noalias(rRightHandSideVector) = ZeroVector(LocalSize); + + // Initialize element data + ElementDataContainer aux_data; + SetElementData(rCurrentProcessInfo, aux_data); + + // Initialize constitutive law parameters + const auto& r_geom = this->GetGeometry(); + const auto p_prop = this->GetProperties(); + ConstitutiveLaw::Parameters cons_law_params(r_geom, p_prop, rCurrentProcessInfo); + + cons_law_params.SetStrainVector(aux_data.StrainRate); + cons_law_params.SetStressVector(aux_data.ShearStress); + cons_law_params.SetConstitutiveMatrix(aux_data.ConstitutiveMatrix); + + auto& cons_law_options = cons_law_params.GetOptions(); + cons_law_options.Set(ConstitutiveLaw::COMPUTE_STRESS); + cons_law_options.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); + + // Calculate kinematics + Vector weights; + Matrix velocity_N; + Matrix pressure_N; + GeometryType::ShapeFunctionsGradientsType velocity_DN; + GeometryType::ShapeFunctionsGradientsType pressure_DN; + DenseVector velocity_DDN; + CalculateKinematics(weights, velocity_N, pressure_N, velocity_DN, pressure_DN, velocity_DDN); + + // Loop Gauss points + const SizeType n_gauss = r_geom.IntegrationPointsNumber(IntegrationMethod); + for (IndexType g = 0; g < n_gauss; ++g) { + // Set current Gauss point kinematics + noalias(aux_data.N_v) = row(velocity_N, g); + noalias(aux_data.N_p) = row(pressure_N, g); + noalias(aux_data.DN_v) = velocity_DN[g]; + noalias(aux_data.DN_p) = pressure_DN[g]; + aux_data.DDN_v = velocity_DDN[g]; + aux_data.Weight = weights[g]; + + // Calculate current Gauss point material response + CalculateStrainRate(aux_data); + mpConstitutiveLaw->CalculateMaterialResponseCauchy(cons_law_params); + mpConstitutiveLaw->CalculateValue(cons_law_params, EFFECTIVE_VISCOSITY, aux_data.EffectiveViscosity); + + // Assemble standard Galerkin contribution + AddGaussPointLeftHandSideContribution(aux_data, rLeftHandSideMatrix); + AddGaussPointRightHandSideContribution(aux_data, rRightHandSideVector); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public Inquiry + +template< unsigned int TDim > +int IncompressibleNavierStokesP2P1Continuous::Check(const ProcessInfo &rCurrentProcessInfo) const +{ + KRATOS_TRY; + int out = Element::Check(rCurrentProcessInfo); + KRATOS_ERROR_IF_NOT(out == 0) + << "Error in base class Check for Element " << this->Info() << std::endl + << "Error code is " << out << std::endl; + + return 0; + + KRATOS_CATCH(""); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Public I/O + +template< unsigned int TDim > +const Parameters IncompressibleNavierStokesP2P1Continuous::GetSpecifications() const +{ + const Parameters specifications = Parameters(R"({ + "time_integration" : ["implicit"], + "framework" : "ale", + "symmetric_lhs" : false, + "positive_definite_lhs" : true, + "output" : { + "gauss_point" : [""], + "nodal_historical" : ["VELOCITY","PRESSURE"], + "nodal_non_historical" : [], + "entity" : [] + }, + "required_variables" : ["VELOCITY","ACCELERATION","MESH_VELOCITY","PRESSURE","IS_STRUCTURE","DISPLACEMENT","BODY_FORCE","NODAL_AREA","NODAL_H","ADVPROJ","DIVPROJ","REACTION","REACTION_WATER_PRESSURE","EXTERNAL_PRESSURE","NORMAL","Y_WALL","Q_VALUE"] + "required_dofs" : [], + "flags_used" : [], + "compatible_geometries" : ["Triangle2D6","Tetrahedra3D10"], + "element_integrates_in_time" : true, + "compatible_constitutive_laws": { + "type" : ["Newtonian2DLaw","Newtonian3DLaw","NewtonianTemperatureDependent2DLaw","NewtonianTemperatureDependent3DLaw","Euler2DLaw","Euler3DLaw"], + "dimension" : ["2D","3D"], + "strain_size" : [3,6] + }, + "required_polynomial_degree_of_geometry" : 2, + "documentation" : + "This implements a div-stable incompressible Navier-Stokes element with bubble function enrichment. No viscous behavior is hardcoded, meaning that any fluid constitutive model can be used through a constitutive law." + })"); + + if (TDim == 2) { + std::vector dofs_2d({"VELOCITY_X","VELOCITY_Y","PRESSURE"}); + specifications["required_dofs"].SetStringArray(dofs_2d); + } else { + std::vector dofs_3d({"VELOCITY_X","VELOCITY_Y","VELOCITY_Z","PRESSURE"}); + specifications["required_dofs"].SetStringArray(dofs_3d); + } + + return specifications; +} + +template< unsigned int TDim > +std::string IncompressibleNavierStokesP2P1Continuous::Info() const +{ + std::stringstream buffer; + buffer << "IncompressibleNavierStokesP2P1Continuous" << TDim << "D" << VelocityNumNodes << "N #" << this->Id(); + return buffer.str(); +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::PrintInfo(std::ostream& rOStream) const +{ + rOStream << this->Info() << std::endl; + + if (mpConstitutiveLaw != nullptr) { + rOStream << "with constitutive law " << std::endl; + mpConstitutiveLaw->PrintInfo(rOStream); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Private operations + +template +void IncompressibleNavierStokesP2P1Continuous::SetElementData( + const ProcessInfo& rProcessInfo, + ElementDataContainer &rData) +{ + // Set nodal data + const auto& r_geom = this->GetGeometry(); + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + const auto& r_v = r_geom[i].FastGetSolutionStepValue(VELOCITY); + const auto& r_v_n = r_geom[i].FastGetSolutionStepValue(VELOCITY, 1); + const auto& r_v_nn = r_geom[i].FastGetSolutionStepValue(VELOCITY, 2); + const auto& r_v_mesh = r_geom[i].FastGetSolutionStepValue(MESH_VELOCITY); + const auto& r_body_force = r_geom[i].FastGetSolutionStepValue(BODY_FORCE); + + for (IndexType d = 0; d < TDim; ++d) { + rData.Velocity(i, d) = r_v[d]; + rData.VelocityOld1(i, d) = r_v_n[d]; + rData.VelocityOld2(i, d) = r_v_nn[d]; + rData.MeshVelocity(i, d) = r_v_mesh[d]; + rData.BodyForce(i, d) = r_body_force[d]; + } + } + + for (IndexType i = 0; i < PressureNumNodes; ++i) { + rData.Pressure[i] = r_geom[i].FastGetSolutionStepValue(PRESSURE); + } + + // Set material values + rData.Density = this->GetProperties().GetValue(DENSITY); + + // Set stabilization values + rData.StabC1 = 12.0; + rData.StabC2 = 2.0; + rData.DynamicTau = rProcessInfo[DYNAMIC_TAU]; + rData.ElementSize = ElementSizeCalculator::AverageElementSize(r_geom); + + // Set ProcessInfo data + rData.DeltaTime = rProcessInfo[DELTA_TIME]; + const auto& r_bdf_coefs = rProcessInfo[BDF_COEFFICIENTS]; + rData.BDF0 = r_bdf_coefs[0]; + rData.BDF1 = r_bdf_coefs[1]; + rData.BDF2 = r_bdf_coefs[2]; +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateKinematics( + Vector& rGaussWeights, + Matrix& rVelocityN, + Matrix& rPressureN, + GeometryType::ShapeFunctionsGradientsType& rVelocityDNDX, + GeometryType::ShapeFunctionsGradientsType& rPressureDNDX, + DenseVector& rVelocityDDNDDX) +{ + // Get element geometry + const auto& r_geom = this->GetGeometry(); + + // Integration rule data + // Note that we use the same for both velocity and pressure interpolations + const SizeType n_gauss = r_geom.IntegrationPointsNumber(IntegrationMethod); + const auto integration_points = r_geom.IntegrationPoints(IntegrationMethod); + + // Calculate Jacobians at integration points + Matrix J; + Matrix inv_J; + double det_J; + Vector det_J_vect(n_gauss); + std::vector> inv_J_vect(n_gauss); + for (IndexType g = 0; g < n_gauss; ++g) { + r_geom.Jacobian(J, g, IntegrationMethod); + MathUtils::InvertMatrix(J, inv_J, det_J); + det_J_vect[g] = det_J; + noalias(inv_J_vect[g]) = inv_J; + } + + // Calculate velocity kinematics from the geometry (P2 interpolation) + rVelocityN = r_geom.ShapeFunctionsValues(IntegrationMethod); + const auto& r_DN_De_v = r_geom.ShapeFunctionsLocalGradients(IntegrationMethod); + if (rVelocityDNDX.size() != n_gauss) { + rVelocityDNDX.resize(n_gauss, false); + } + for (IndexType g = 0; g < n_gauss; ++g) { + rVelocityDNDX[g] = prod(r_DN_De_v[g], inv_J_vect[g]); + } + GeometryUtils::ShapeFunctionsSecondDerivativesTransformOnAllIntegrationPoints(rVelocityDDNDDX, r_geom, IntegrationMethod); + + // Calculate pressure kinematics from an auxiliary geometry (P1 interpolation) + GeometryType::UniquePointer p_aux_geom = nullptr; + if constexpr (TDim == 2) { + p_aux_geom = Kratos::make_unique>(r_geom(0), r_geom(1), r_geom(2)); + } else { + p_aux_geom = Kratos::make_unique>(r_geom(0), r_geom(1), r_geom(2), r_geom(3)); + } + rPressureN = p_aux_geom->ShapeFunctionsValues(IntegrationMethod); + if (rPressureDNDX.size() != n_gauss) { + rPressureDNDX.resize(n_gauss, false); + } + const auto& r_DN_De_p = p_aux_geom->ShapeFunctionsLocalGradients(IntegrationMethod); + for (IndexType g = 0; g < n_gauss; ++g) { + rPressureDNDX[g] = prod(r_DN_De_p[g], inv_J_vect[g]); + } + + // Calculate integration points weight + if (rGaussWeights.size() != n_gauss) { + rGaussWeights.resize(n_gauss, false); + } + for (IndexType g = 0; g < n_gauss; ++g) { + rGaussWeights[g] = det_J_vect[g] * integration_points[g].Weight(); + } +} + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::CalculateStrainRate(ElementDataContainer& rData) +{ + if (rData.StrainRate.size() != StrainSize) { + rData.StrainRate.resize(StrainSize, false); + } + noalias(rData.StrainRate) = ZeroVector(StrainSize); + + if constexpr (TDim == 2) { + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rData.StrainRate[0] += rData.DN_v(i,0)*rData.Velocity(i,0); + rData.StrainRate[1] += rData.DN_v(i,1)*rData.Velocity(i,1); + rData.StrainRate[2] += rData.DN_v(i,0)*rData.Velocity(i,1) + rData.DN_v(i,1)*rData.Velocity(i,0); + } + } else { + for (IndexType i = 0; i < VelocityNumNodes; ++i) { + rData.StrainRate[0] += rData.DN_v(i,0)*rData.Velocity(i,0); + rData.StrainRate[1] += rData.DN_v(i,1)*rData.Velocity(i,1); + rData.StrainRate[2] += rData.DN_v(i,2)*rData.Velocity(i,2); + rData.StrainRate[3] += rData.DN_v(i,0)*rData.Velocity(i,1) + rData.DN_v(i,1)*rData.Velocity(i,0); + rData.StrainRate[4] += rData.DN_v(i,1)*rData.Velocity(i,2) + rData.DN_v(i,2)*rData.Velocity(i,1); + rData.StrainRate[5] += rData.DN_v(i,0)*rData.Velocity(i,2) + rData.DN_v(i,2)*rData.Velocity(i,0); + } + } + +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<2>::AddGaussPointLeftHandSideContribution( + const ElementDataContainer& rData, + MatrixType& rLHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Calculate convective velocity + const BoundedMatrix vconv = rData.Velocity - rData.MeshVelocity; + + // Get constitutive matrix + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble LHS contribution + const double gauss_weight = rData.Weight; + //substitute_lhs_2D +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<3>::AddGaussPointLeftHandSideContribution( + const ElementDataContainer& rData, + MatrixType& rLHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Calculate convective velocity + const BoundedMatrix vconv = rData.Velocity - rData.MeshVelocity; + + // Get constitutive matrix + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble LHS contribution + const double gauss_weight = rData.Weight; + //substitute_lhs_3D +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<2>::AddGaussPointRightHandSideContribution( + const ElementDataContainer& rData, + VectorType& rRHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Get nodal data + const auto& r_v = rData.Velocity; + const auto& r_vn = rData.VelocityOld1; + const auto& r_vnn = rData.VelocityOld2; + const auto& r_vmesh = rData.MeshVelocity; + const auto& r_f = rData.BodyForce; + const auto& r_p = rData.Pressure; + + // Calculate convective velocity + const BoundedMatrix vconv = r_v - r_vmesh; + + // Get stress from material response + const auto& r_stress = rData.ShearStress; + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble RHS contribution + const double gauss_weight = rData.Weight; + //substitute_rhs_2D +} + +template <> +void IncompressibleNavierStokesP2P1Continuous<3>::AddGaussPointRightHandSideContribution( + const ElementDataContainer& rData, + VectorType& rRHS) +{ + // Get material data + const double rho = rData.Density; + const double mu = rData.EffectiveViscosity; + + // Get stabilization data + const double h = rData.ElementSize; + const double stab_c1 = rData.StabC1; + const double stab_c2 = rData.StabC2; + const double dyn_tau = rData.DynamicTau; + + // Get nodal data + const auto& r_v = rData.Velocity; + const auto& r_vn = rData.VelocityOld1; + const auto& r_vnn = rData.VelocityOld2; + const auto& r_vmesh = rData.MeshVelocity; + const auto& r_f = rData.BodyForce; + const auto& r_p = rData.Pressure; + + // Calculate convective velocity + const BoundedMatrix vconv = r_v - r_vmesh; + + // Get stress from material response + const auto& r_stress = rData.ShearStress; + const auto& C = rData.ConstitutiveMatrix; + + // Get shape function values + const auto& N_p = rData.N_p; + const auto& N_v = rData.N_v; + const auto& DN_p = rData.DN_p; + const auto& DN_v = rData.DN_v; + const auto& DDN_v = rData.DDN_v; + + // Assemble RHS contribution + const double gauss_weight = rData.Weight; + //substitute_rhs_3D +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Private serialization + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::save(Serializer& rSerializer) const +{ + KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, Element); +} + + +template< unsigned int TDim > +void IncompressibleNavierStokesP2P1Continuous::load(Serializer& rSerializer) +{ + KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, Element); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// +// Class template instantiation + +template class IncompressibleNavierStokesP2P1Continuous<2>; +template class IncompressibleNavierStokesP2P1Continuous<3>; + +} \ No newline at end of file diff --git a/applications/FluidDynamicsApplication/tests/cpp_tests/test_incompressible_navier_stokes_p2_p1_continuous_element.cpp b/applications/FluidDynamicsApplication/tests/cpp_tests/test_incompressible_navier_stokes_p2_p1_continuous_element.cpp new file mode 100644 index 000000000000..2200b65dbb29 --- /dev/null +++ b/applications/FluidDynamicsApplication/tests/cpp_tests/test_incompressible_navier_stokes_p2_p1_continuous_element.cpp @@ -0,0 +1,210 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + +// System includes +#include // for std::setprecision + +// External includes + + +// Project includes +#include "testing/testing.h" +#include "containers/model.h" +#include "includes/model_part.h" +#include "includes/cfd_variables.h" + +// Application includes +#include "custom_constitutive/newtonian_2d_law.h" +#include "custom_constitutive/newtonian_3d_law.h" +#include "custom_elements/incompressible_navier_stokes_p2_p1_continuous.h" + +namespace Kratos::Testing { + +KRATOS_TEST_CASE_IN_SUITE(IncompressibleNavierStokesP2P1Continuous2D6N, FluidDynamicsApplicationFastSuite) +{ + Model model; + unsigned int buffer_size = 3; + auto& r_model_part = model.CreateModelPart("TestModelPart", buffer_size); + + // Variables addition + r_model_part.AddNodalSolutionStepVariable(BODY_FORCE); + r_model_part.AddNodalSolutionStepVariable(PRESSURE); + r_model_part.AddNodalSolutionStepVariable(VELOCITY); + r_model_part.AddNodalSolutionStepVariable(MESH_VELOCITY); + r_model_part.AddNodalSolutionStepVariable(ACCELERATION); + r_model_part.AddNodalSolutionStepVariable(NODAL_AREA); + r_model_part.AddNodalSolutionStepVariable(REACTION); + r_model_part.AddNodalSolutionStepVariable(REACTION_WATER_PRESSURE); + + // ProcessInfo container fill + double delta_time = 0.1; + r_model_part.GetProcessInfo().SetValue(DELTA_TIME, delta_time); + Vector bdf_coefs(3); + bdf_coefs[0] = 3.0 / (2.0 * delta_time); + bdf_coefs[1] = -2.0 / delta_time; + bdf_coefs[2] = 0.5 * delta_time; + r_model_part.GetProcessInfo().SetValue(BDF_COEFFICIENTS, bdf_coefs); + + // Set the element properties + auto p_properties = r_model_part.CreateNewProperties(0); + p_properties->SetValue(DENSITY, 1.0); + p_properties->SetValue(DYNAMIC_VISCOSITY, 1.0e-3); + p_properties->SetValue(CONSTITUTIVE_LAW, Kratos::make_shared()); + + // Element creation + r_model_part.CreateNewNode(1, 0.0, 0.0, 0.0); + r_model_part.CreateNewNode(2, 1.0, 0.1, 0.0); + r_model_part.CreateNewNode(3, 1.0, 0.9, 0.0); + r_model_part.CreateNewNode(4, 0.5, 0.05, 0.0); + r_model_part.CreateNewNode(5, 1.0, 0.5, 0.0); + r_model_part.CreateNewNode(6, 0.5, 0.45, 0.0); + + for (auto it_node = r_model_part.NodesBegin(); it_node < r_model_part.NodesEnd(); ++it_node){ + it_node->AddDof(VELOCITY_X,REACTION_X); + it_node->AddDof(VELOCITY_Y,REACTION_Y); + it_node->AddDof(PRESSURE,REACTION_WATER_PRESSURE); + } + + std::vector element_nodes {1, 2, 3, 4, 5, 6}; + auto p_elem = r_model_part.CreateNewElement("IncompressibleNavierStokesP2P1Continuous2D6N", 1, element_nodes, p_properties); + + // Define and set the nodal values + Matrix reference_velocity(6,2); + reference_velocity(0,0) = 0.0; reference_velocity(0,1) = 0.1; + reference_velocity(1,0) = 0.1; reference_velocity(1,1) = 0.2; + reference_velocity(2,0) = 0.2; reference_velocity(2,1) = 0.3; + reference_velocity(3,0) = 0.4; reference_velocity(3,1) = 0.4; + reference_velocity(4,0) = 0.5; reference_velocity(4,1) = 0.5; + reference_velocity(5,0) = 0.6; reference_velocity(5,1) = 0.6; + + auto& r_geometry = r_model_part.ElementsBegin()->GetGeometry(); + for(std::size_t i = 0; i < 6; ++i){ + r_geometry[i].FastGetSolutionStepValue(PRESSURE) = 0.0; + for(std::size_t k = 0; k < 2; ++k){ + r_geometry[i].FastGetSolutionStepValue(VELOCITY)[k] = reference_velocity(i,k); + r_geometry[i].FastGetSolutionStepValue(VELOCITY, 1)[k] = 0.9*reference_velocity(i,k); + r_geometry[i].FastGetSolutionStepValue(VELOCITY, 2)[k] = 0.7*reference_velocity(i,k); + } + } + + // Calculate RHS and LHS + Vector RHS = ZeroVector(15); + Matrix LHS = ZeroMatrix(15,15); + const auto& r_process_info = r_model_part.GetProcessInfo(); + p_elem->Initialize(r_process_info); + p_elem->CalculateLocalSystem(LHS, RHS, r_process_info); + + // std::cout << p_elem->Info() << std::setprecision(12) << std::endl; + // KRATOS_WATCH(RHS) + // KRATOS_WATCH(row(LHS,0)) + + // Check values + const std::vector rhs_ref = {-0.00906903569079,-0.0216587001242,-0.0178476996397,-0.0172703814363,0.0834031923607,0.0915008945538,-0.00823181605452,0.0498746884469,0.351823061946,0.322803675622,0.158034060439,0.142938341794,-0.3377346826,-0.0527051752743,0.295439857875}; + const std::vector lhs_0_ref = {0.275040358619,2.13488594544e-06,0.029996360203,-0.0100000622721,0.0293109266242,0.0095065886921,-0.18426639514,0.041493102637,-0.0301319829049,0.000495608465964,-0.127955089696,-0.0414973724089,0.13386705482,-0.000600436672153,6.67151857946e-05}; + KRATOS_EXPECT_VECTOR_NEAR(RHS, rhs_ref, 1.0e-10) + KRATOS_EXPECT_VECTOR_NEAR(row(LHS,0), lhs_0_ref, 1.0e-10) +} + +KRATOS_TEST_CASE_IN_SUITE(IncompressibleNavierStokesP2P1Continuous3D10N, FluidDynamicsApplicationFastSuite) +{ + Model model; + unsigned int buffer_size = 3; + auto& r_model_part = model.CreateModelPart("TestModelPart", buffer_size); + + // Variables addition + r_model_part.AddNodalSolutionStepVariable(BODY_FORCE); + r_model_part.AddNodalSolutionStepVariable(PRESSURE); + r_model_part.AddNodalSolutionStepVariable(VELOCITY); + r_model_part.AddNodalSolutionStepVariable(MESH_VELOCITY); + r_model_part.AddNodalSolutionStepVariable(ACCELERATION); + r_model_part.AddNodalSolutionStepVariable(NODAL_AREA); + r_model_part.AddNodalSolutionStepVariable(REACTION); + r_model_part.AddNodalSolutionStepVariable(REACTION_WATER_PRESSURE); + + // ProcessInfo container fill + double delta_time = 0.1; + r_model_part.GetProcessInfo().SetValue(DELTA_TIME, delta_time); + Vector bdf_coefs(3); + bdf_coefs[0] = 3.0 / (2.0 * delta_time); + bdf_coefs[1] = -2.0 / delta_time; + bdf_coefs[2] = 0.5 * delta_time; + r_model_part.GetProcessInfo().SetValue(BDF_COEFFICIENTS, bdf_coefs); + + // Set the element properties + auto p_properties = r_model_part.CreateNewProperties(0); + p_properties->SetValue(DENSITY, 1.0); + p_properties->SetValue(DYNAMIC_VISCOSITY, 1.0e-3); + p_properties->SetValue(CONSTITUTIVE_LAW, Kratos::make_shared()); + + // Element creation + r_model_part.CreateNewNode(1, 0.0, 0.0, 0.0); + r_model_part.CreateNewNode(2, 1.0, 0.1, 0.0); + r_model_part.CreateNewNode(3, 1.0, 0.9, 0.0); + r_model_part.CreateNewNode(4, 0.0, 0.0, 1.0); + r_model_part.CreateNewNode(5, 0.5, 0.05, 0.0); + r_model_part.CreateNewNode(6, 1.0, 0.5, 0.0); + r_model_part.CreateNewNode(7, 0.5, 0.45, 0.0); + r_model_part.CreateNewNode(8, 0.0, 0.0, 0.5); + r_model_part.CreateNewNode(9, 0.5, 0.05, 0.5); + r_model_part.CreateNewNode(10, 0.5, 0.45, 0.5); + + for (auto it_node = r_model_part.NodesBegin(); it_node < r_model_part.NodesEnd(); ++it_node){ + it_node->AddDof(VELOCITY_X,REACTION_X); + it_node->AddDof(VELOCITY_Y,REACTION_Y); + it_node->AddDof(PRESSURE,REACTION_WATER_PRESSURE); + } + + std::vector element_nodes {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + auto p_elem = r_model_part.CreateNewElement("IncompressibleNavierStokesP2P1Continuous3D10N", 1, element_nodes, p_properties); + + // Define and set the nodal values + Matrix reference_velocity(10,3); + reference_velocity(0,0) = 0.0; reference_velocity(0,1) = 0.1; reference_velocity(0,2) = 0.2; + reference_velocity(1,0) = 0.1; reference_velocity(1,1) = 0.2; reference_velocity(1,2) = 0.4; + reference_velocity(2,0) = 0.2; reference_velocity(2,1) = 0.3; reference_velocity(2,2) = 0.6; + reference_velocity(3,0) = 0.4; reference_velocity(3,1) = 0.4; reference_velocity(3,2) = 0.8; + reference_velocity(4,0) = 0.5; reference_velocity(4,1) = 0.5; reference_velocity(4,2) = 1.0; + reference_velocity(5,0) = 0.6; reference_velocity(5,1) = 0.6; reference_velocity(5,2) = 1.2; + reference_velocity(6,0) = 0.0; reference_velocity(6,1) = 0.1; reference_velocity(6,2) = 0.2; + reference_velocity(7,0) = 0.1; reference_velocity(7,1) = 0.2; reference_velocity(7,2) = 0.4; + reference_velocity(8,0) = 0.2; reference_velocity(8,1) = 0.3; reference_velocity(8,2) = 0.6; + reference_velocity(9,0) = 0.4; reference_velocity(9,1) = 0.4; reference_velocity(9,2) = 0.8; + + auto& r_geometry = r_model_part.ElementsBegin()->GetGeometry(); + for(std::size_t i = 0; i < 10; ++i){ + r_geometry[i].FastGetSolutionStepValue(PRESSURE) = 0.0; + for(std::size_t k = 0; k < 3; ++k){ + r_geometry[i].FastGetSolutionStepValue(VELOCITY)[k] = reference_velocity(i,k); + r_geometry[i].FastGetSolutionStepValue(VELOCITY, 1)[k] = 0.9*reference_velocity(i,k); + r_geometry[i].FastGetSolutionStepValue(VELOCITY, 2)[k] = 0.7*reference_velocity(i,k); + } + } + + // Calculate RHS and LHS + Vector RHS = ZeroVector(34); + Matrix LHS = ZeroMatrix(34,34); + const auto& r_process_info = r_model_part.GetProcessInfo(); + p_elem->Initialize(r_process_info); + p_elem->CalculateLocalSystem(LHS, RHS, r_process_info); + + // std::cout << p_elem->Info() << std::setprecision(12) << std::endl; + // KRATOS_WATCH(RHS) + // KRATOS_WATCH(row(LHS,0)) + + // Check values + const std::vector rhs_ref = {-0.00657701934375,-0.00620550235972,-0.0136913620863,-0.000170114993796,-0.0143517156581,-0.0157786851078,-0.00860833486305,-0.0150132458839,-0.0189512865026,-0.0130363146785,-0.011378009438,-0.0250112171768,-0.0242266633507,-0.0170353120096,-0.0450749598297,0.0346452605859,0.0609125107186,0.098362051396,0.0160967983649,0.0035688376663,0.0250792755284,0.0237285184092,0.0190965941479,0.0416218137988,0.0449979595942,0.0685522075529,0.120269383925,0.0474728594943,0.0547584464252,0.120148974574,-0.119401045188,-0.0123259565984,0.00846909310257,0.0482579086839}; + const std::vector lhs_0_ref = {0.0257086073875,3.0423641244e-06,0.00522857129039,0.0178570580167,-0.00186127586489,3.38504920949e-05,0.0158010322097,0.00253394525089,-3.28579639389e-06,0.018188732577,0,0.00162630966951,-0.0629346872215,0.00488268545444,-0.00284951737883,0.0131204630345,-0.000669627021879,2.58110017567e-05,-0.0763856921432,-0.00488877018269,-0.00327692855409,-0.0802590504228,1.90236453582e-20,-0.00679850526245,0.0139363248065,-0.00357526747101,0.00275600539288,0.00355834628902,0.00357526747101,0.00325768914512,0.0207605910311,-0.00752233157666,-0.00657159278778,-0.00666666666667}; + KRATOS_EXPECT_VECTOR_NEAR(RHS, rhs_ref, 1.0e-10) + KRATOS_EXPECT_VECTOR_NEAR(row(LHS,0), lhs_0_ref, 1.0e-10) +} + +} // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/FluidDynamicsApplication/tests/cpp_tests/test_navier_stokes_p2_p1_continuous_wall_condition.cpp b/applications/FluidDynamicsApplication/tests/cpp_tests/test_navier_stokes_p2_p1_continuous_wall_condition.cpp new file mode 100644 index 000000000000..544054c73fd8 --- /dev/null +++ b/applications/FluidDynamicsApplication/tests/cpp_tests/test_navier_stokes_p2_p1_continuous_wall_condition.cpp @@ -0,0 +1,148 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Ruben Zorrilla +// + + +// Project includes +#include "testing/testing.h" +#include "containers/model.h" +#include "includes/model_part.h" +#include "includes/cfd_variables.h" + +// Application includes +#include "fluid_dynamics_application.h" + +namespace Kratos::Testing { + +namespace +{ + auto CreateTestingNavierStokesWallCondition2D3N( + const std::string ConditionName, + ModelPart& rModelPart) + { + // Add required nodal variables + rModelPart.AddNodalSolutionStepVariable(NORMAL); + rModelPart.AddNodalSolutionStepVariable(VELOCITY); + rModelPart.AddNodalSolutionStepVariable(PRESSURE); + rModelPart.AddNodalSolutionStepVariable(BODY_FORCE); + rModelPart.AddNodalSolutionStepVariable(MESH_VELOCITY); + rModelPart.AddNodalSolutionStepVariable(EXTERNAL_PRESSURE); + + // Set the required properties + // Note that the condition DENSITY is retrieved from the element one + auto p_properties_0 = rModelPart.CreateNewProperties(0); + auto p_properties_1 = rModelPart.CreateNewProperties(1); + p_properties_1->SetValue(DENSITY, 1000.0); + p_properties_1->SetValue(DYNAMIC_VISCOSITY, 2.0); + auto p_cons_law = Kratos::make_shared(); + p_properties_1->SetValue(CONSTITUTIVE_LAW, p_cons_law); + + // Create a fake element to serve as parent of current testing condition + rModelPart.CreateNewNode(1, 0.0, 0.0, 0.0); + rModelPart.CreateNewNode(2, 1.0, 0.0, 0.0); + rModelPart.CreateNewNode(3, 0.0, 1.0, 0.0); + rModelPart.CreateNewNode(4, 0.5, 0.0, 0.0); + rModelPart.CreateNewNode(5, 0.5, 0.5, 0.0); + rModelPart.CreateNewNode(6, 0.0, 0.5, 0.0); + auto p_element = rModelPart.CreateNewElement("IncompressibleNavierStokesP2P1Continuous2D6N", 1, {1,2,3,4,5,6}, p_properties_1); + p_element->Initialize(rModelPart.GetProcessInfo()); // Initialize constitutive law + + // Create the testing condition + auto p_test_condition = rModelPart.CreateNewCondition(ConditionName, 1, {{3,1,2}}, p_properties_0); + + // Add DOFs + for (auto& r_node : rModelPart.Nodes()){ + r_node.AddDof(VELOCITY_X); + r_node.AddDof(VELOCITY_Y); + r_node.AddDof(PRESSURE); + } + + // Manually set the NORMALS + array_1d aux_normal = ZeroVector(3); + aux_normal[0] = -1.0; + rModelPart.pGetNode(1)->FastGetSolutionStepValue(NORMAL) = aux_normal; + rModelPart.pGetNode(3)->FastGetSolutionStepValue(NORMAL) = aux_normal; + + // Manually set the element as condition neighbour + GlobalPointersVector neigh_vect; + neigh_vect.resize(1); + neigh_vect(0) = p_element; + p_test_condition->SetValue(NEIGHBOUR_ELEMENTS, neigh_vect); + + return p_test_condition; + } +} + +KRATOS_TEST_CASE_IN_SUITE(NavierStokesP2P1ContinuousWallCondition2D3NZero, FluidDynamicsApplicationFastSuite) +{ + // Create the test model part + Model model; + std::size_t buffer_size = 2; + auto& r_model_part = model.CreateModelPart("TestModelPart",buffer_size); + + // Create the testing condition + auto p_test_condition = CreateTestingNavierStokesWallCondition2D3N("NavierStokesP2P1ContinuousWallCondition2D3N", r_model_part); + + // Set the testing nodal values + array_1d aux_v = ZeroVector(3); + for (auto& r_node: r_model_part.Nodes()) { + aux_v[0] = r_node.Id(); + aux_v[1] = 2.0*r_node.Id(); + r_node.FastGetSolutionStepValue(VELOCITY) = aux_v; + } + + // Calculate the RHS and LHS + // Note that in this case it must have zero contribution + Vector RHS; + Matrix LHS; + p_test_condition->CalculateLocalSystem(LHS, RHS, r_model_part.GetProcessInfo()); + + // Check results + KRATOS_EXPECT_VECTOR_NEAR(RHS, ZeroVector(8), 1.0e-12) + KRATOS_EXPECT_MATRIX_NEAR(LHS, ZeroMatrix(8,8), 1.0e-12) +} + +KRATOS_TEST_CASE_IN_SUITE(NavierStokesP2P1ContinuousWallCondition2D3NOutletInflow, FluidDynamicsApplicationFastSuite) +{ + // Create the test model part + Model model; + std::size_t buffer_size = 2; + auto& r_model_part = model.CreateModelPart("TestModelPart",buffer_size); + + // Create the testing condition + auto p_test_condition = CreateTestingNavierStokesWallCondition2D3N("NavierStokesP2P1ContinuousWallCondition2D3N", r_model_part); + + // Set the testing nodal values + array_1d aux_v = ZeroVector(3); + for (auto& r_node: r_model_part.Nodes()) { + aux_v[0] = r_node.Id(); + aux_v[1] = 2.0*r_node.Id(); + r_node.FastGetSolutionStepValue(VELOCITY) = aux_v; + } + + // Activate the outlet inflow contribution and set required values + p_test_condition->Set(OUTLET, true); + r_model_part.GetProcessInfo().SetValue(CHARACTERISTIC_VELOCITY, 1.0); + r_model_part.GetProcessInfo().SetValue(OUTLET_INFLOW_CONTRIBUTION_SWITCH, true); + + // Calculate the RHS and LHS + // Note that in this case the LHS must have zero contribution + Vector RHS; + Matrix LHS; + p_test_condition->CalculateLocalSystem(LHS, RHS, r_model_part.GetProcessInfo()); + + // Check results + std::vector rhs_out = {-14456.1331739, 0, -382.691792867, 0, -14336.9944223, 0, 0, 0}; + KRATOS_EXPECT_VECTOR_NEAR(RHS, rhs_out, 1.0e-8) + KRATOS_EXPECT_MATRIX_NEAR(LHS, ZeroMatrix(8,8), 1.0e-12) +} + +} // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.cpp b/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.cpp new file mode 100644 index 000000000000..c0aac4633104 --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.cpp @@ -0,0 +1,56 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// +// Main authors: Mohamed Nabi +// John van Esch +// + +#include "custom_conditions/Pw_point_flux_condition.hpp" + +namespace Kratos +{ + +template +PwPointFluxCondition::PwPointFluxCondition() : PwCondition() +{ +} + +template +PwPointFluxCondition::PwPointFluxCondition(IndexType NewId, GeometryType::Pointer pGeometry) + : PwCondition(NewId, pGeometry) +{ +} + +template +PwPointFluxCondition::PwPointFluxCondition(IndexType NewId, + GeometryType::Pointer pGeometry, + PropertiesType::Pointer pProperties) + : PwCondition(NewId, pGeometry, pProperties) +{ +} + +template +Condition::Pointer PwPointFluxCondition::Create(IndexType NewId, + NodesArrayType const& rThisNodes, + PropertiesType::Pointer pProperties) const +{ + return Kratos::make_intrusive(NewId, this->GetGeometry().Create(rThisNodes), pProperties); +} + +template +void PwPointFluxCondition::CalculateRHS(Vector& rRightHandSideVector, const ProcessInfo&) +{ + rRightHandSideVector[0] = this->GetGeometry()[0].FastGetSolutionStepValue(NORMAL_FLUID_FLUX); +} + +template class PwPointFluxCondition<2, 1>; +template class PwPointFluxCondition<3, 1>; + +} // Namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.hpp b/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.hpp new file mode 100644 index 000000000000..3bb5772425ae --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_conditions/Pw_point_flux_condition.hpp @@ -0,0 +1,63 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// +// Main authors: Mohamed Nabi +// John van Esch +// + +#pragma once + +#include "custom_conditions/Pw_condition.hpp" +#include "includes/serializer.h" + +namespace Kratos +{ + +template +class KRATOS_API(GEO_MECHANICS_APPLICATION) PwPointFluxCondition : public PwCondition +{ +public: + using GeometryType = Geometry; + using PropertiesType = Properties; + using NodesArrayType = GeometryType::PointsArrayType; + using BaseType = PwCondition; + + KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(PwPointFluxCondition); + + PwPointFluxCondition(); + + PwPointFluxCondition(IndexType NewId, GeometryType::Pointer pGeometry); + + PwPointFluxCondition(IndexType NewId, GeometryType::Pointer pGeometry, PropertiesType::Pointer pProperties); + + ~PwPointFluxCondition() override = default; + + Condition::Pointer Create(IndexType NewId, + NodesArrayType const& rThisNodes, + PropertiesType::Pointer pProperties) const override; + +protected: + void CalculateRHS(Vector& rRightHandSideVector, const ProcessInfo&) override; + +private: + friend class Serializer; + + void save(Serializer& rSerializer) const override + { + KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, BaseType) + } + + void load(Serializer& rSerializer) override + { + KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, BaseType) + } +}; + +} // namespace Kratos \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/custom_conditions/surface_normal_load_3D_diff_order_condition.cpp b/applications/GeoMechanicsApplication/custom_conditions/surface_normal_load_3D_diff_order_condition.cpp index 77f6fbce4a4e..15807ccbb578 100644 --- a/applications/GeoMechanicsApplication/custom_conditions/surface_normal_load_3D_diff_order_condition.cpp +++ b/applications/GeoMechanicsApplication/custom_conditions/surface_normal_load_3D_diff_order_condition.cpp @@ -14,7 +14,7 @@ // Project includes #include "custom_conditions/surface_normal_load_3D_diff_order_condition.hpp" -#include "custom_utilities/math_utilities.h" +#include "utilities/math_utils.h" namespace Kratos { diff --git a/applications/GeoMechanicsApplication/custom_constitutive/linear_elastic_plane_stress_2D_law.h b/applications/GeoMechanicsApplication/custom_constitutive/linear_elastic_plane_stress_2D_law.h index 8292f7d2f1b4..eeefca345e7b 100644 --- a/applications/GeoMechanicsApplication/custom_constitutive/linear_elastic_plane_stress_2D_law.h +++ b/applications/GeoMechanicsApplication/custom_constitutive/linear_elastic_plane_stress_2D_law.h @@ -13,6 +13,7 @@ #pragma once // Project includes +#include "geo_mechanics_application_constants.h" #include "linear_elastic_law.h" namespace Kratos @@ -57,7 +58,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoLinearElasticPlaneStress2DLaw : p static constexpr SizeType Dimension = 2; /// Static definition of the VoigtSize - static constexpr SizeType VoigtSize = 3; + static constexpr SizeType VoigtSize = VOIGT_SIZE_2D_PLANE_STRESS; /// Counted pointer of GeoLinearElasticPlaneStress2DLaw KRATOS_CLASS_POINTER_DEFINITION(GeoLinearElasticPlaneStress2DLaw); diff --git a/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.cpp b/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.cpp index 23406d72c15d..0c1e3ce53b4d 100644 --- a/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.cpp +++ b/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.cpp @@ -19,8 +19,6 @@ namespace Kratos { -GeoThermalDispersionLaw::GeoThermalDispersionLaw() : mNumberOfDimensions{2} {} - GeoThermalDispersionLaw::GeoThermalDispersionLaw(std::size_t NumberOfDimensions) : mNumberOfDimensions{NumberOfDimensions} { @@ -28,21 +26,11 @@ GeoThermalDispersionLaw::GeoThermalDispersionLaw(std::size_t NumberOfDimensions) << "Got invalid number of dimensions: " << mNumberOfDimensions << std::endl; } -ConstitutiveLaw::Pointer GeoThermalDispersionLaw::Clone() const +Matrix GeoThermalDispersionLaw::CalculateThermalDispersionMatrix(const Properties& rProp) const { - return Kratos::make_shared(*this); -} - -SizeType GeoThermalDispersionLaw::WorkingSpaceDimension() { return mNumberOfDimensions; } - -Matrix GeoThermalDispersionLaw::CalculateThermalDispersionMatrix(const Properties& rProp, - const ProcessInfo& rProcessInfo) const -{ - KRATOS_TRY - Matrix result = ZeroMatrix(mNumberOfDimensions, mNumberOfDimensions); - RetentionLaw::Parameters parameters(rProp, rProcessInfo); + RetentionLaw::Parameters parameters(rProp); auto retention_law = RetentionLawFactory::Clone(rProp); const double saturation = retention_law->CalculateSaturation(parameters); const double water_fraction = rProp[POROSITY] * saturation; @@ -53,7 +41,7 @@ Matrix GeoThermalDispersionLaw::CalculateThermalDispersionMatrix(const Propertie water_fraction * rProp[THERMAL_CONDUCTIVITY_WATER]; if (mNumberOfDimensions >= 2) { - const auto y = static_cast(indexThermalFlux::Y); + const auto y = static_cast(indexThermalFlux::Y); result(x, y) = solid_fraction * rProp[THERMAL_CONDUCTIVITY_SOLID_XY]; result(y, y) = solid_fraction * rProp[THERMAL_CONDUCTIVITY_SOLID_YY] + water_fraction * rProp[THERMAL_CONDUCTIVITY_WATER]; @@ -70,8 +58,6 @@ Matrix GeoThermalDispersionLaw::CalculateThermalDispersionMatrix(const Propertie } return result; - - KRATOS_CATCH("") } } // Namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.h b/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.h index b92ebd2a46f1..e61545557e6d 100644 --- a/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.h +++ b/applications/GeoMechanicsApplication/custom_constitutive/thermal_dispersion_law.h @@ -14,48 +14,36 @@ #pragma once -#include "includes/constitutive_law.h" +#include "custom_constitutive/thermal_law.h" namespace Kratos { class RetentionLaw; -/** - * @class GeoThermalDispersionLaw - * @ingroup GeoMechanicsApplication - * @brief This class defines the thermal dispersion for heat cases - */ -class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoThermalDispersionLaw : public ConstitutiveLaw +class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoThermalDispersionLaw : public GeoThermalLaw { public: - /// Counted pointer of GeoThermalDispersionLaw KRATOS_CLASS_POINTER_DEFINITION(GeoThermalDispersionLaw); - GeoThermalDispersionLaw(); + GeoThermalDispersionLaw() = default; explicit GeoThermalDispersionLaw(SizeType NumberOfDimensions); - ConstitutiveLaw::Pointer Clone() const override; - - SizeType WorkingSpaceDimension() override; - - Matrix CalculateThermalDispersionMatrix(const Properties& rProp, const ProcessInfo& rProcessInfo) const; + [[nodiscard]] Matrix CalculateThermalDispersionMatrix(const Properties& rProp) const override; private: - SizeType mNumberOfDimensions; + std::size_t mNumberOfDimensions = 2; friend class Serializer; void save(Serializer& rSerializer) const override { - KRATOS_SERIALIZE_SAVE_BASE_CLASS(rSerializer, ConstitutiveLaw) rSerializer.save("NumberOfDimensions", mNumberOfDimensions); } void load(Serializer& rSerializer) override { - KRATOS_SERIALIZE_LOAD_BASE_CLASS(rSerializer, ConstitutiveLaw) rSerializer.load("NumberOfDimensions", mNumberOfDimensions); } }; diff --git a/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.cpp b/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.cpp new file mode 100644 index 000000000000..9f6bc3919a86 --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.cpp @@ -0,0 +1,25 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Mohamed Nabi +// John van Esch +// + +#include "custom_constitutive/thermal_filter_law.h" +#include "geo_mechanics_application_variables.h" + +namespace Kratos +{ + +Matrix GeoThermalFilterLaw::CalculateThermalDispersionMatrix(const Properties& rProp) const +{ + return ScalarMatrix(1, 1, rProp[THERMAL_CONDUCTIVITY_WATER]); +} + +} // Namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.h b/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.h new file mode 100644 index 000000000000..813ecb1716d1 --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_constitutive/thermal_filter_law.h @@ -0,0 +1,41 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Mohamed Nabi +// John van Esch +// + +#pragma once + +#include "custom_constitutive/thermal_law.h" + +namespace Kratos +{ + +class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoThermalFilterLaw : public GeoThermalLaw +{ +public: + KRATOS_CLASS_POINTER_DEFINITION(GeoThermalFilterLaw); + + [[nodiscard]] Matrix CalculateThermalDispersionMatrix(const Properties& rProp) const override; + +private: + friend class Serializer; + + void save(Serializer&) const override + { + // Nothing to serialize, since there are no data members, and its base class is abstract + } + + void load(Serializer&) override + { + // Nothing to serialize, since there are no data members, and its base class is abstract + } +}; +} // namespace Kratos. diff --git a/applications/GeoMechanicsApplication/custom_constitutive/thermal_law.h b/applications/GeoMechanicsApplication/custom_constitutive/thermal_law.h new file mode 100644 index 000000000000..cacdaa7a5e9e --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_constitutive/thermal_law.h @@ -0,0 +1,39 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Mohamed Nabi +// John van Esch +// Gennady Markelov +// + +#pragma once + +#include "geo_mechanics_application_variables.h" +#include "includes/serializer.h" + +namespace Kratos +{ + +class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoThermalLaw +{ +public: + KRATOS_CLASS_POINTER_DEFINITION(GeoThermalLaw); + + virtual ~GeoThermalLaw() = default; + + [[nodiscard]] virtual Matrix CalculateThermalDispersionMatrix(const Properties& rProp) const = 0; + +private: + friend class Serializer; + + virtual void save(Serializer& rSerializer) const = 0; + + virtual void load(Serializer& rSerializer) = 0; +}; +} // namespace Kratos. diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.cpp index 1d2648c0726c..615f096acb87 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.cpp @@ -14,6 +14,7 @@ // Application includes #include "custom_elements/U_Pw_small_strain_FIC_element.hpp" #include "custom_utilities/math_utilities.h" +#include "custom_utilities/transport_equation_utilities.hpp" namespace Kratos { @@ -46,6 +47,7 @@ void UPwSmallStrainFICElement::Initialize(const ProcessInfo& rC UPwBaseElement::Initialize(rCurrentProcessInfo); + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); for (unsigned int i = 0; i < TDim; ++i) { mNodalConstitutiveTensor[i].resize(VoigtSize); @@ -135,30 +137,25 @@ void UPwSmallStrainFICElement::InitializeNonLinearIteration(con } Matrix DtStressContainer(NumGPoints, TDim); - Vector StressVector(VoigtSize); + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); + Vector StressVector(VoigtSize); const auto b_matrices = this->CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, VoigtSize); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; + Variables.B = b_matrices[GPoint]; + Variables.F = deformation_gradients[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; - // Compute infinitessimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); this->SaveGPConstitutiveTensor(ConstitutiveTensorContainer, Variables.ConstitutiveMatrix, GPoint); // Compute DtStress @@ -196,31 +193,24 @@ void UPwSmallStrainFICElement::FinalizeNonLinearIteration(const // Containers for extrapolation variables Matrix DtStressContainer(NumGPoints, TDim); - Vector StressVector(VoigtSize); + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); + Vector StressVector(VoigtSize); const auto b_matrices = this->CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, VoigtSize); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitessimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // Compute ConstitutiveTensor - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); + Variables.B = b_matrices[GPoint]; + Variables.F = deformation_gradients[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; // Compute DtStress noalias(Variables.StrainVector) = prod(Variables.B, Variables.VelocityVector); @@ -297,12 +287,11 @@ void UPwSmallStrainFICElement<2, 3>::ExtrapolateGPConstitutiveTensor(const array BoundedMatrix ExtrapolationMatrix; this->CalculateExtrapolationMatrix(ExtrapolationMatrix); - BoundedMatrix AuxNodalConstitutiveTensor; - + Matrix AuxNodalConstitutiveTensor(NumNodes, this->GetStressStatePolicy().GetVoigtSize()); for (unsigned int i = 0; i < Dim; ++i) { noalias(AuxNodalConstitutiveTensor) = prod(ExtrapolationMatrix, ConstitutiveTensorContainer[i]); - for (unsigned int j = 0; j < VoigtSize; j++) + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) noalias(mNodalConstitutiveTensor[i][j]) = column(AuxNodalConstitutiveTensor, j); } @@ -334,7 +323,8 @@ void UPwSmallStrainFICElement<2, 4>::ExtrapolateGPConstitutiveTensor(const array BoundedMatrix ExtrapolationMatrix; this->CalculateExtrapolationMatrix(ExtrapolationMatrix); - BoundedMatrix AuxNodalConstitutiveTensor; + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); + Matrix AuxNodalConstitutiveTensor(NumNodes, VoigtSize); for (unsigned int i = 0; i < Dim; ++i) { noalias(AuxNodalConstitutiveTensor) = prod(ExtrapolationMatrix, ConstitutiveTensorContainer[i]); @@ -360,7 +350,8 @@ void UPwSmallStrainFICElement<3, 4>::ExtrapolateGPConstitutiveTensor(const array BoundedMatrix ExtrapolationMatrix; this->CalculateExtrapolationMatrix(ExtrapolationMatrix); - BoundedMatrix AuxNodalConstitutiveTensor; + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); + Matrix AuxNodalConstitutiveTensor(NumNodes, VoigtSize); for (unsigned int i = 0; i < Dim; ++i) { noalias(AuxNodalConstitutiveTensor) = prod(ExtrapolationMatrix, ConstitutiveTensorContainer[i]); @@ -385,7 +376,8 @@ void UPwSmallStrainFICElement<3, 8>::ExtrapolateGPConstitutiveTensor(const array BoundedMatrix ExtrapolationMatrix; this->CalculateExtrapolationMatrix(ExtrapolationMatrix); - BoundedMatrix AuxNodalConstitutiveTensor; + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); + Matrix AuxNodalConstitutiveTensor(NumNodes, VoigtSize); for (unsigned int i = 0; i < Dim; ++i) { noalias(AuxNodalConstitutiveTensor) = prod(ExtrapolationMatrix, ConstitutiveTensorContainer[i]); @@ -454,52 +446,44 @@ void UPwSmallStrainFICElement::CalculateAll(MatrixType& rLeftHa FICElementVariables FICVariables; this->InitializeFICElementVariables(FICVariables, Variables.DN_DXContainer, Geom, Prop, CurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); - - const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto b_matrices = this->CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = + GeoTransportEquationUtilities::CalculateBiotCoefficients(constitutive_matrices, Prop); + const auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); - // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - // Compute Np, GradNpT, B and StrainVector this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitessimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + Variables.B = b_matrices[GPoint]; + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; GeoElementUtilities::CalculateNuMatrix(Variables.Nu, Variables.NContainer, GPoint); GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - // Compute ShapeFunctionsSecondOrderGradients this->CalculateShapeFunctionsSecondOrderGradients(FICVariables, Variables); - - // Compute constitutive tensor and stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - // set shear modulus from stiffness matrix FICVariables.ShearModulus = CalculateShearModulus(Variables.ConstitutiveMatrix); - // calculate Bulk modulus from stiffness matrix - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, Variables.DerivativeOfSaturation, Prop); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; @@ -731,6 +715,7 @@ void UPwSmallStrainFICElement<2, 3>::InitializeSecondOrderTerms(FICElementVariab const SizeType Dim = 2; + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); for (unsigned int i = 0; i < Dim; ++i) rFICVariables.ConstitutiveTensorGradients[i].resize(VoigtSize); @@ -748,6 +733,7 @@ void UPwSmallStrainFICElement<2, 4>::InitializeSecondOrderTerms(FICElementVariab const SizeType NumNodes = 4; // Voigt identity matrix + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); rFICVariables.VoigtMatrix.resize(VoigtSize, VoigtSize, false); noalias(rFICVariables.VoigtMatrix) = ZeroMatrix(VoigtSize, VoigtSize); rFICVariables.VoigtMatrix(0, 0) = 1.0; @@ -771,8 +757,8 @@ void UPwSmallStrainFICElement<3, 4>::InitializeSecondOrderTerms(FICElementVariab { KRATOS_TRY - const SizeType Dim = 3; - + const SizeType Dim = 3; + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); for (unsigned int i = 0; i < Dim; ++i) rFICVariables.ConstitutiveTensorGradients[i].resize(VoigtSize); @@ -791,6 +777,7 @@ void UPwSmallStrainFICElement<3, 8>::InitializeSecondOrderTerms(FICElementVariab const SizeType NumNodes = 8; // Voigt identity matrix + auto const VoigtSize = this->GetStressStatePolicy().GetVoigtSize(); rFICVariables.VoigtMatrix.resize(VoigtSize, VoigtSize, false); noalias(rFICVariables.VoigtMatrix) = ZeroMatrix(VoigtSize, VoigtSize); rFICVariables.VoigtMatrix(0, 0) = 1.0; @@ -1017,7 +1004,7 @@ void UPwSmallStrainFICElement<2, 3>::CalculateConstitutiveTensorGradients(FICEle const SizeType NumNodes = 3; for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { for (unsigned int k = 0; k < Dim; k++) { rFICVariables.ConstitutiveTensorGradients[i][j][k] = 0.0; @@ -1029,7 +1016,7 @@ void UPwSmallStrainFICElement<2, 3>::CalculateConstitutiveTensorGradients(FICEle } for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { rFICVariables.DimVoigtMatrix(i, j) = 0.0; for (unsigned int k = 0; k < Dim; k++) @@ -1066,7 +1053,7 @@ void UPwSmallStrainFICElement<2, 4>::CalculateConstitutiveTensorGradients(FICEle const SizeType NumNodes = 4; for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { for (unsigned int k = 0; k < Dim; k++) { rFICVariables.ConstitutiveTensorGradients[i][j][k] = 0.0; @@ -1078,7 +1065,7 @@ void UPwSmallStrainFICElement<2, 4>::CalculateConstitutiveTensorGradients(FICEle } for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { rFICVariables.DimVoigtMatrix(i, j) = 0.0; for (unsigned int k = 0; k < Dim; k++) @@ -1130,7 +1117,7 @@ void UPwSmallStrainFICElement<3, 4>::CalculateConstitutiveTensorGradients(FICEle const SizeType NumNodes = 4; for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { for (unsigned int k = 0; k < Dim; k++) { rFICVariables.ConstitutiveTensorGradients[i][j][k] = 0.0; @@ -1142,7 +1129,7 @@ void UPwSmallStrainFICElement<3, 4>::CalculateConstitutiveTensorGradients(FICEle } for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { rFICVariables.DimVoigtMatrix(i, j) = 0.0; for (unsigned int k = 0; k < Dim; k++) @@ -1166,7 +1153,7 @@ void UPwSmallStrainFICElement<3, 8>::CalculateConstitutiveTensorGradients(FICEle const SizeType NumNodes = 8; for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { for (unsigned int k = 0; k < Dim; k++) { rFICVariables.ConstitutiveTensorGradients[i][j][k] = 0.0; @@ -1178,7 +1165,7 @@ void UPwSmallStrainFICElement<3, 8>::CalculateConstitutiveTensorGradients(FICEle } for (unsigned int i = 0; i < Dim; ++i) { - for (unsigned int j = 0; j < VoigtSize; j++) { + for (unsigned int j = 0; j < this->GetStressStatePolicy().GetVoigtSize(); j++) { rFICVariables.DimVoigtMatrix(i, j) = 0.0; for (unsigned int k = 0; k < Dim; k++) diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.hpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.hpp index 9699e2fcc011..ca314292f984 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_FIC_element.hpp @@ -46,10 +46,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainFICElement using UPwBaseElement::mStressVector; using UPwBaseElement::mStateVariablesFinalized; using UPwBaseElement::mThisIntegrationMethod; - - using UPwSmallStrainElement::CalculateBulkModulus; - using UPwSmallStrainElement::VoigtSize; - + using ElementVariables = typename UPwSmallStrainElement::ElementVariables; ///---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.cpp index 915720c57a96..bedd3bd6d209 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.cpp @@ -13,6 +13,7 @@ // Application includes #include "custom_elements/U_Pw_small_strain_element.hpp" +#include "custom_utilities/constitutive_law_utilities.hpp" #include "custom_utilities/equation_of_motion_utilities.h" #include "custom_utilities/math_utilities.h" #include "custom_utilities/transport_equation_utilities.hpp" @@ -148,15 +149,15 @@ void UPwSmallStrainElement::InitializeSolutionStep(const Proces ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // Create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); const auto determinants_of_deformation_gradients = GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -169,8 +170,9 @@ void UPwSmallStrainElement::InitializeSolutionStep(const Proces Variables.detF = determinants_of_deformation_gradients[GPoint]; Variables.StrainVector = strain_vectors[GPoint]; - // Set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Np, Variables.GradNpT, Variables.F, Variables.detF); // Initialize constitutive law noalias(Variables.StressVector) = mStressVector[GPoint]; @@ -251,44 +253,24 @@ void UPwSmallStrainElement::InitializeNonLinearIteration(const { KRATOS_TRY - // Defining necessary variables - const GeometryType& rGeom = this->GetGeometry(); - const IndexType NumGPoints = rGeom.IntegrationPointsNumber(mThisIntegrationMethod); - - // Create constitutive law parameters: + const GeometryType& rGeom = this->GetGeometry(); ConstitutiveLaw::Parameters ConstitutiveParameters(rGeom, this->GetProperties(), rCurrentProcessInfo); ConstitutiveParameters.Set(ConstitutiveLaw::COMPUTE_STRESS); ConstitutiveParameters.Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); ConstitutiveParameters.Set(ConstitutiveLaw::INITIALIZE_MATERIAL_RESPONSE); // Note: this is for nonlocal damage - // Element variables ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); - - // Loop over integration points - for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // Set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // Compute Stress - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - } + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); KRATOS_CATCH("") } @@ -321,15 +303,15 @@ void UPwSmallStrainElement::FinalizeSolutionStep(const ProcessI ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // Create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); const auto determinants_of_deformation_gradients = GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); Matrix StressContainer(NumGPoints, mStressVector[0].size()); // Loop over integration points @@ -342,8 +324,9 @@ void UPwSmallStrainElement::FinalizeSolutionStep(const ProcessI Variables.detF = determinants_of_deformation_gradients[GPoint]; Variables.StrainVector = strain_vectors[GPoint]; - // Set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Np, Variables.GradNpT, Variables.F, Variables.detF); // Compute constitutive tensor and/or stresses noalias(Variables.StressVector) = mStressVector[GPoint]; @@ -405,8 +388,9 @@ void UPwSmallStrainElement::ExtrapolateGPValues(const Matrix& S array_1d NodalStressVector; // List with stresses at each node array_1d NodalStressTensor; + auto const StressTensorSize = this->GetStressStatePolicy().GetStressTensorSize(); for (unsigned int iNode = 0; iNode < TNumNodes; ++iNode) { - NodalStressVector[iNode].resize(VoigtSize); + NodalStressVector[iNode].resize(this->GetStressStatePolicy().GetVoigtSize()); NodalStressTensor[iNode].resize(StressTensorSize, StressTensorSize); } @@ -414,7 +398,7 @@ void UPwSmallStrainElement::ExtrapolateGPValues(const Matrix& S this->CalculateExtrapolationMatrix(ExtrapolationMatrix); Matrix AuxNodalStress; - AuxNodalStress.resize(TNumNodes, VoigtSize); + AuxNodalStress.resize(TNumNodes, this->GetStressStatePolicy().GetVoigtSize()); noalias(AuxNodalStress) = prod(ExtrapolationMatrix, StressContainer); /* INFO: @@ -531,22 +515,27 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { // Compute Np, GradNpT, B and StrainVector this->CalculateKinematics(Variables, GPoint); - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); - - if (rVariable == DEGREE_OF_SATURATION) rOutput[GPoint] = Variables.DegreeOfSaturation; - if (rVariable == EFFECTIVE_SATURATION) rOutput[GPoint] = Variables.EffectiveSaturation; - if (rVariable == BISHOP_COEFFICIENT) rOutput[GPoint] = Variables.BishopCoefficient; - if (rVariable == DERIVATIVE_OF_SATURATION) - rOutput[GPoint] = Variables.DerivativeOfSaturation; - if (rVariable == RELATIVE_PERMEABILITY) - rOutput[GPoint] = Variables.RelativePermeability; + RetentionParameters.SetFluidPressure(GeoTransportEquationUtilities::CalculateFluidPressure( + Variables.Np, Variables.PressureVector)); + + if (rVariable == DEGREE_OF_SATURATION) + rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateSaturation(RetentionParameters); + else if (rVariable == EFFECTIVE_SATURATION) + rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateEffectiveSaturation(RetentionParameters); + else if (rVariable == BISHOP_COEFFICIENT) + rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateBishopCoefficient(RetentionParameters); + else if (rVariable == DERIVATIVE_OF_SATURATION) + rOutput[GPoint] = + mRetentionLawVector[GPoint]->CalculateDerivativeOfSaturation(RetentionParameters); + else if (rVariable == RELATIVE_PERMEABILITY) + rOutput[GPoint] = + mRetentionLawVector[GPoint]->CalculateRelativePermeability(RetentionParameters); } } else if (rVariable == HYDRAULIC_HEAD) { const PropertiesType& rProp = this->GetProperties(); @@ -565,7 +554,7 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const rOutput[GPoint] = HydraulicHead; } } else if (rVariable == CONFINED_STIFFNESS || rVariable == SHEAR_STIFFNESS) { - size_t variable_index; + size_t variable_index = 0; if (rVariable == CONFINED_STIFFNESS) { if (TDim == 2) { variable_index = INDEX_2D_PLANE_STRAIN_XX; @@ -594,38 +583,25 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); - - for (unsigned int GPoint = 0; GPoint < mConstitutiveLawVector.size(); ++GPoint) { - const PropertiesType& rProp = this->GetProperties(); - - ConstitutiveLaw::Parameters ConstitutiveParameters(rGeom, rProp, rCurrentProcessInfo); - ConstitutiveParameters.Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); - ConstitutiveParameters.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); - - // Compute Np, GradNpT, B and StrainVector - this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, this->GetStressStatePolicy().GetVoigtSize()); - // set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + const PropertiesType& rProp = this->GetProperties(); - // compute constitutive tensor and/or stresses - noalias(Variables.StressVector) = mStressVector[GPoint]; - ConstitutiveParameters.SetStressVector(Variables.StressVector); + ConstitutiveLaw::Parameters ConstitutiveParameters(rGeom, rProp, rCurrentProcessInfo); + ConstitutiveParameters.Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); + ConstitutiveParameters.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); - rOutput[GPoint] = Variables.ConstitutiveMatrix(variable_index, variable_index); - } + std::transform(constitutive_matrices.begin(), constitutive_matrices.end(), rOutput.begin(), + [variable_index](const Matrix& constitutive_matrix) { + return constitutive_matrix(variable_index, variable_index); + }); } else if (r_prop.Has(rVariable)) { // Map initial material property to gauss points, as required for the output rOutput.clear(); @@ -658,15 +634,14 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints( const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); - - std::vector permeability_update_factors; - for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - permeability_update_factors.push_back(this->CalculatePermeabilityUpdateFactor(strain_vectors[GPoint])); - } - - const auto fluid_fluxes = CalculateFluidFluxes(permeability_update_factors, rCurrentProcessInfo); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, this->GetStressStatePolicy().GetVoigtSize()); + + const auto fluid_fluxes = + CalculateFluidFluxes(GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + strain_vectors, this->GetProperties()), + rCurrentProcessInfo); for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { GeoElementUtilities::FillArray1dOutput(rOutput[GPoint], fluid_fluxes[GPoint]); } @@ -714,57 +689,32 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // Create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); - Vector VoigtVector(mStressVector[0].size()); - noalias(VoigtVector) = ZeroVector(VoigtVector.size()); - - for (unsigned int i = 0; i < StressTensorSize; ++i) - VoigtVector[i] = 1.0; - - const bool hasBiotCoefficient = rProp.Has(BIOT_COEFFICIENT); - - Vector TotalStressVector(mStressVector[0].size()); + const Vector& VoigtVector = this->GetStressStatePolicy().GetVoigtVector(); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); - // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - // Compute Np, GradNpT, B and StrainVector this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // Set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // Compute constitutive tensor and/or stresses - noalias(Variables.StressVector) = mStressVector[GPoint]; - ConstitutiveParameters.SetStressVector(Variables.StressVector); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - - Variables.BiotCoefficient = CalculateBiotCoefficient(Variables, hasBiotCoefficient); - - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); - - noalias(TotalStressVector) = mStressVector[GPoint]; - noalias(TotalStressVector) += PORE_PRESSURE_SIGN_FACTOR * Variables.BiotCoefficient * - Variables.BishopCoefficient * Variables.FluidPressure * VoigtVector; - - if (rOutput[GPoint].size() != TotalStressVector.size()) - rOutput[GPoint].resize(TotalStressVector.size(), false); - - rOutput[GPoint] = TotalStressVector; + const auto fluid_pressure = GeoTransportEquationUtilities::CalculateFluidPressure( + Variables.Np, Variables.PressureVector); + RetentionParameters.SetFluidPressure(fluid_pressure); + const auto bishop_coefficient = + mRetentionLawVector[GPoint]->CalculateBishopCoefficient(RetentionParameters); + + rOutput[GPoint] = mStressVector[GPoint] + PORE_PRESSURE_SIGN_FACTOR * biot_coefficients[GPoint] * + bishop_coefficient * fluid_pressure * VoigtVector; } } else if (rVariable == ENGINEERING_STRAIN_VECTOR) { // Definition of variables @@ -782,7 +732,8 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const Variables.B = this->CalculateBMatrix(Variables.GradNpTInitialConfiguration, Variables.Np); // Compute infinitesimal strain - Variables.StrainVector = this->CalculateCauchyStrain(Variables.B, Variables.DisplacementVector); + Variables.StrainVector = + StressStrainUtilities::CalculateCauchyStrain(Variables.B, Variables.DisplacementVector); if (rOutput[GPoint].size() != Variables.StrainVector.size()) rOutput[GPoint].resize(Variables.StrainVector.size(), false); @@ -795,8 +746,9 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - rOutput = CalculateStrains(deformation_gradients, b_matrices, Variables.DisplacementVector, - Variables.UseHenckyStrain); + rOutput = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, this->GetStressStatePolicy().GetVoigtSize()); } else if (rProp.Has(rVariable)) { // Map initial material property to Gauss points, as required for the output rOutput.clear(); @@ -822,6 +774,7 @@ void UPwSmallStrainElement::CalculateOnIntegrationPoints(const if (rOutput.size() != NumGPoints) rOutput.resize(NumGPoints); if (rVariable == CAUCHY_STRESS_TENSOR) { + auto const StressTensorSize = this->GetStressStatePolicy().GetStressTensorSize(); for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { rOutput[GPoint].resize(StressTensorSize, StressTensorSize, false); rOutput[GPoint] = MathUtils::StressVectorToTensor(mStressVector[GPoint]); @@ -895,7 +848,6 @@ void UPwSmallStrainElement::CalculateMaterialStiffnessMatrix(Ma const GeometryType& rGeom = this->GetGeometry(); const GeometryType::IntegrationPointsArrayType& IntegrationPoints = rGeom.IntegrationPoints(mThisIntegrationMethod); - const IndexType NumGPoints = IntegrationPoints.size(); // Constitutive Law parameters ConstitutiveLaw::Parameters ConstitutiveParameters(rGeom, rProp, rCurrentProcessInfo); @@ -906,36 +858,20 @@ void UPwSmallStrainElement::CalculateMaterialStiffnessMatrix(Ma this->InitializeElementVariables(Variables, rCurrentProcessInfo); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); - - for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - // Compute Np, GradNpT, B and StrainVector - this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto integration_coefficients = + this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); - // Set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + const auto stiffness_matrix = GeoEquationOfMotionUtilities::CalculateStiffnessMatrix( + b_matrices, constitutive_matrices, integration_coefficients); - // Compute constitutive tensor - noalias(Variables.StressVector) = mStressVector[GPoint]; - ConstitutiveParameters.SetStressVector(Variables.StressVector); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - - // Compute weighting coefficient for integration - Variables.IntegrationCoefficient = - this->CalculateIntegrationCoefficient(IntegrationPoints[GPoint], Variables.detJ); - - // Compute stiffness matrix - this->CalculateAndAddStiffnessMatrix(rStiffnessMatrix, Variables); - } + GeoElementUtilities::AssembleUUBlockMatrix(rStiffnessMatrix, stiffness_matrix); KRATOS_CATCH("") } @@ -978,8 +914,7 @@ void UPwSmallStrainElement::CalculateMassMatrix(MatrixType& rMa const auto N_container = r_geom.ShapeFunctionsValues(integration_method); const auto degrees_saturation = GeoTransportEquationUtilities::CalculateDegreesSaturation( - this->GetPressureSolutionVector(), N_container, mRetentionLawVector, this->GetProperties(), - rCurrentProcessInfo); + this->GetPressureSolutionVector(), N_container, mRetentionLawVector, this->GetProperties()); const auto solid_densities = GeoTransportEquationUtilities::CalculateSoilDensities(degrees_saturation, this->GetProperties()); @@ -1026,46 +961,48 @@ void UPwSmallStrainElement::CalculateAll(MatrixType& rLe ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // Create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); - - const bool hasBiotCoefficient = rProp.Has(BIOT_COEFFICIENT); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto b_matrices = CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); + auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); + const auto permeability_update_factors = GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + strain_vectors, this->GetProperties()); + std::transform(relative_permeability_values.cbegin(), relative_permeability_values.cend(), + permeability_update_factors.cbegin(), relative_permeability_values.begin(), + std::multiplies{}); for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - // Compute GradNpT, B and StrainVector this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // Set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + Variables.B = b_matrices[GPoint]; + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; // Compute Nu and BodyAcceleration GeoElementUtilities::CalculateNuMatrix(Variables.Nu, Variables.NContainer, GPoint); GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - // Compute constitutive tensor and stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); - - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); - Variables.PermeabilityUpdateFactor = this->CalculatePermeabilityUpdateFactor(Variables.StrainVector); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; @@ -1083,52 +1020,6 @@ void UPwSmallStrainElement::CalculateAll(MatrixType& rLe KRATOS_CATCH("") } -template -double UPwSmallStrainElement::CalculateBiotCoefficient(const ElementVariables& rVariables, - bool hasBiotCoefficient) const -{ - KRATOS_TRY - - const PropertiesType& rProp = this->GetProperties(); - - // Properties variables - if (hasBiotCoefficient) { - return rProp[BIOT_COEFFICIENT]; - } else { - // Calculate Bulk modulus from stiffness matrix - const double BulkModulus = CalculateBulkModulus(rVariables.ConstitutiveMatrix); - return 1.0 - BulkModulus / rProp[BULK_MODULUS_SOLID]; - } - - KRATOS_CATCH("") -} - -template -void UPwSmallStrainElement::InitializeBiotCoefficients(ElementVariables& rVariables, - bool hasBiotCoefficient) -{ - KRATOS_TRY - - const PropertiesType& rProp = this->GetProperties(); - - // Properties variables - rVariables.BiotCoefficient = CalculateBiotCoefficient(rVariables, hasBiotCoefficient); - - if (!rProp[IGNORE_UNDRAINED]) { - rVariables.BiotModulusInverse = - (rVariables.BiotCoefficient - rProp[POROSITY]) / rProp[BULK_MODULUS_SOLID] + - rProp[POROSITY] / rProp[BULK_MODULUS_FLUID]; - } else { - rVariables.BiotModulusInverse = - (rVariables.BiotCoefficient - rProp[POROSITY]) / rProp[BULK_MODULUS_SOLID] + rProp[POROSITY] / TINY; - } - - rVariables.BiotModulusInverse *= rVariables.DegreeOfSaturation; - rVariables.BiotModulusInverse -= rVariables.DerivativeOfSaturation * rProp[POROSITY]; - - KRATOS_CATCH("") -} - template std::vector> UPwSmallStrainElement::CalculateFluidFluxes( const std::vector& rPermeabilityUpdateFactors, const ProcessInfo& rCurrentProcessInfo) @@ -1142,64 +1033,31 @@ std::vector> UPwSmallStrainElement::Calc const PropertiesType& rProp = this->GetProperties(); - array_1d GradPressureTerm; - - // Create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); + std::transform(relative_permeability_values.cbegin(), relative_permeability_values.cend(), + rPermeabilityUpdateFactors.cbegin(), relative_permeability_values.begin(), + std::multiplies<>{}); for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { this->CalculateKinematics(Variables, GPoint); - Variables.PermeabilityUpdateFactor = rPermeabilityUpdateFactors[GPoint]; GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - Variables.FluidPressure = CalculateFluidPressure(Variables); - RetentionParameters.SetFluidPressure(Variables.FluidPressure); - Variables.RelativePermeability = - mRetentionLawVector[GPoint]->CalculateRelativePermeability(RetentionParameters); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - noalias(GradPressureTerm) = prod(trans(Variables.GradNpT), Variables.PressureVector); - noalias(GradPressureTerm) += PORE_PRESSURE_SIGN_FACTOR * rProp[DENSITY_WATER] * Variables.BodyAcceleration; + array_1d GradPressureTerm = prod(trans(Variables.GradNpT), Variables.PressureVector); + GradPressureTerm += PORE_PRESSURE_SIGN_FACTOR * rProp[DENSITY_WATER] * Variables.BodyAcceleration; FluidFluxes.push_back(PORE_PRESSURE_SIGN_FACTOR * Variables.DynamicViscosityInverse * - Variables.RelativePermeability * Variables.PermeabilityUpdateFactor * + Variables.RelativePermeability * prod(Variables.PermeabilityMatrix, GradPressureTerm)); } return FluidFluxes; } -template -double UPwSmallStrainElement::CalculatePermeabilityUpdateFactor(const Vector& rStrainVector) const -{ - KRATOS_TRY - - if (const auto& r_prop = this->GetProperties(); r_prop[PERMEABILITY_CHANGE_INVERSE_FACTOR] > 0.0) { - const double InverseCK = r_prop[PERMEABILITY_CHANGE_INVERSE_FACTOR]; - const double epsV = StressStrainUtilities::CalculateTrace(rStrainVector); - const double ePrevious = r_prop[POROSITY] / (1.0 - r_prop[POROSITY]); - const double eCurrent = (1.0 + ePrevious) * std::exp(epsV) - 1.0; - const double permLog10 = (eCurrent - ePrevious) * InverseCK; - return std::pow(10.0, permLog10); - } - - return 1.0; - - KRATOS_CATCH("") -} - -template -double UPwSmallStrainElement::CalculateBulkModulus(const Matrix& ConstitutiveMatrix) const -{ - KRATOS_TRY - - const int IndexG = ConstitutiveMatrix.size1() - 1; - return ConstitutiveMatrix(0, 0) - (4.0 / 3.0) * ConstitutiveMatrix(IndexG, IndexG); - - KRATOS_CATCH("") -} - template void UPwSmallStrainElement::InitializeElementVariables(ElementVariables& rVariables, const ProcessInfo& rCurrentProcessInfo) @@ -1227,10 +1085,9 @@ void UPwSmallStrainElement::InitializeElementVariables(ElementV rVariables.detF = 1.0; // General Variables - rVariables.VoigtVector = ZeroVector(VoigtSize); - std::fill_n(rVariables.VoigtVector.begin(), StressTensorSize, 1.0); + rVariables.VoigtVector = this->GetStressStatePolicy().GetVoigtVector(); - rVariables.B = ZeroMatrix(VoigtSize, TNumNodes * TDim); + rVariables.B = ZeroMatrix(this->GetStressStatePolicy().GetVoigtSize(), TNumNodes * TDim); const GeometryType& rGeom = this->GetGeometry(); const IndexType NumGPoints = rGeom.IntegrationPointsNumber(mThisIntegrationMethod); @@ -1245,15 +1102,15 @@ void UPwSmallStrainElement::InitializeElementVariables(ElementV rVariables.DN_DXContainer, rVariables.detJContainer, mThisIntegrationMethod); // Constitutive Law parameters - rVariables.StressVector.resize(VoigtSize, false); - rVariables.StrainVector.resize(VoigtSize, false); - rVariables.ConstitutiveMatrix.resize(VoigtSize, VoigtSize, false); + rVariables.StressVector.resize(this->GetStressStatePolicy().GetVoigtSize(), false); + rVariables.StrainVector.resize(this->GetStressStatePolicy().GetVoigtSize(), false); + rVariables.ConstitutiveMatrix.resize(this->GetStressStatePolicy().GetVoigtSize(), + this->GetStressStatePolicy().GetVoigtSize(), false); // Auxiliary variables - rVariables.UVoigtMatrix.resize(TNumNodes * TDim, VoigtSize, false); + rVariables.UVoigtMatrix.resize(TNumNodes * TDim, this->GetStressStatePolicy().GetVoigtSize(), false); // Retention law - rVariables.FluidPressure = 0.0; rVariables.DegreeOfSaturation = 1.0; rVariables.DerivativeOfSaturation = 0.0; rVariables.RelativePermeability = 1.0; @@ -1291,7 +1148,12 @@ void UPwSmallStrainElement::CalculateAndAddLHS(MatrixType& rLef if (!rVariables.IgnoreUndrained) { this->CalculateAndAddCouplingMatrix(rLeftHandSideMatrix, rVariables); - this->CalculateAndAddPermeabilityMatrix(rLeftHandSideMatrix, rVariables); + + const auto permeability_matrix = + GeoTransportEquationUtilities::CalculatePermeabilityMatrix( + rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, + rVariables.RelativePermeability, rVariables.IntegrationCoefficient); + GeoElementUtilities::AssemblePPBlockMatrix(rLeftHandSideMatrix, permeability_matrix); } KRATOS_CATCH("") @@ -1303,11 +1165,9 @@ void UPwSmallStrainElement::CalculateAndAddStiffnessMatrix(Matr { KRATOS_TRY - noalias(rVariables.UVoigtMatrix) = prod(trans(rVariables.B), rVariables.ConstitutiveMatrix); - noalias(rVariables.UUMatrix) = prod(rVariables.UVoigtMatrix, rVariables.B) * rVariables.IntegrationCoefficient; - - // Distribute stiffness block matrix into the elemental matrix - GeoElementUtilities::AssembleUUBlockMatrix(rLeftHandSideMatrix, rVariables.UUMatrix); + const auto stiffness_matrix = GeoEquationOfMotionUtilities::CalculateStiffnessMatrixGPoint( + rVariables.B, rVariables.ConstitutiveMatrix, rVariables.IntegrationCoefficient); + GeoElementUtilities::AssembleUUBlockMatrix(rLeftHandSideMatrix, stiffness_matrix); KRATOS_CATCH("") } @@ -1353,22 +1213,6 @@ void UPwSmallStrainElement::CalculateAndAddCompressibilityMatri KRATOS_CATCH("") } -template -void UPwSmallStrainElement::CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, - const ElementVariables& rVariables) -{ - KRATOS_TRY - - const auto permeability_matrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( - rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, - rVariables.RelativePermeability, rVariables.PermeabilityUpdateFactor, rVariables.IntegrationCoefficient); - - // Distribute permeability block matrix into the elemental matrix - GeoElementUtilities::AssemblePPBlockMatrix(rLeftHandSideMatrix, permeability_matrix); - - KRATOS_CATCH("") -} - template void UPwSmallStrainElement::CalculateAndAddRHS(VectorType& rRightHandSideVector, ElementVariables& rVariables, @@ -1403,7 +1247,6 @@ void UPwSmallStrainElement::CalculateAndAddStiffnessForce(Vecto noalias(rVariables.UVector) = -1.0 * prod(trans(rVariables.B), mStressVector[GPoint]) * rVariables.IntegrationCoefficient; - // Distribute stiffness block vector into elemental vector GeoElementUtilities::AssembleUBlockVector(rRightHandSideVector, rVariables.UVector); KRATOS_CATCH("") @@ -1507,13 +1350,30 @@ void UPwSmallStrainElement::CalculatePermeabilityFlow( rPermeabilityMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, - rVariables.RelativePermeability, rVariables.PermeabilityUpdateFactor, rVariables.IntegrationCoefficient); + rVariables.RelativePermeability, rVariables.IntegrationCoefficient); noalias(rPVector) = -prod(rPermeabilityMatrix, rVariables.PressureVector); KRATOS_CATCH("") } +template +std::vector UPwSmallStrainElement::CalculateRelativePermeabilityValues( + const std::vector& rFluidPressures) const +{ + KRATOS_ERROR_IF_NOT(rFluidPressures.size() == mRetentionLawVector.size()); + + auto retention_law_params = RetentionLaw::Parameters{this->GetProperties()}; + + auto result = std::vector{}; + std::transform(mRetentionLawVector.begin(), mRetentionLawVector.end(), rFluidPressures.begin(), + std::back_inserter(result), [&retention_law_params](auto pRetentionLaw, auto FluidPressure) { + retention_law_params.SetFluidPressure(FluidPressure); + return pRetentionLaw->CalculateRelativePermeability(retention_law_params); + }); + return result; +} + template void UPwSmallStrainElement::CalculateAndAddPermeabilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) @@ -1538,8 +1398,7 @@ void UPwSmallStrainElement::CalculateFluidBodyFlow(BoundedMatri noalias(rPDimMatrix) = prod(rVariables.GradNpT, rVariables.PermeabilityMatrix) * rVariables.IntegrationCoefficient; noalias(rPVector) = rVariables.DynamicViscosityInverse * rVariables.FluidDensity * - rVariables.RelativePermeability * rVariables.PermeabilityUpdateFactor * - prod(rPDimMatrix, rVariables.BodyAcceleration); + rVariables.RelativePermeability * prod(rPDimMatrix, rVariables.BodyAcceleration); KRATOS_CATCH("") } @@ -1558,38 +1417,6 @@ void UPwSmallStrainElement::CalculateAndAddFluidBodyFlow(Vector KRATOS_CATCH("") } -template -Vector UPwSmallStrainElement::CalculateStrain(const Matrix& rDeformationGradient, - const Matrix& rB, - const Vector& rDisplacements, - bool UseHenckyStrain) const -{ - return UseHenckyStrain ? StressStrainUtilities::CalculateHenckyStrain(rDeformationGradient, VoigtSize) - : this->CalculateCauchyStrain(rB, rDisplacements); -} - -template -std::vector UPwSmallStrainElement::CalculateStrains(const std::vector& rDeformationGradients, - const std::vector& rBs, - const Vector& rDisplacements, - bool UseHenckyStrain) const -{ - std::vector result; - std::transform( - rDeformationGradients.begin(), rDeformationGradients.end(), rBs.begin(), std::back_inserter(result), - [this, &rDisplacements, UseHenckyStrain](const auto& rDeformationGradient, const auto& rB) { - return CalculateStrain(rDeformationGradient, rB, rDisplacements, UseHenckyStrain); - }); - - return result; -} - -template -Vector UPwSmallStrainElement::CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements) const -{ - return prod(rB, rDisplacements); -} - template Vector UPwSmallStrainElement::CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const { @@ -1697,8 +1524,6 @@ void UPwSmallStrainElement::InitializeProperties(ElementVariabl rVariables.Porosity = rProp[POROSITY]; GeoElementUtilities::FillPermeabilityMatrix(rVariables.PermeabilityMatrix, rProp); - rVariables.PermeabilityUpdateFactor = 1.0; - KRATOS_CATCH("") } @@ -1720,43 +1545,6 @@ void UPwSmallStrainElement::CalculateKinematics(ElementVariable KRATOS_CATCH("") } -template -void UPwSmallStrainElement::SetConstitutiveParameters(ElementVariables& rVariables, - ConstitutiveLaw::Parameters& rConstitutiveParameters) -{ - KRATOS_TRY - - rConstitutiveParameters.SetStrainVector(rVariables.StrainVector); - rConstitutiveParameters.SetConstitutiveMatrix(rVariables.ConstitutiveMatrix); - rConstitutiveParameters.SetShapeFunctionsValues(rVariables.Np); - rConstitutiveParameters.SetShapeFunctionsDerivatives(rVariables.GradNpT); - rConstitutiveParameters.SetDeformationGradientF(rVariables.F); - rConstitutiveParameters.SetDeterminantF(rVariables.detF); - - KRATOS_CATCH("") -} - -template -void UPwSmallStrainElement::SetRetentionParameters(const ElementVariables& rVariables, - RetentionLaw::Parameters& rRetentionParameters) -{ - KRATOS_TRY - - rRetentionParameters.SetFluidPressure(rVariables.FluidPressure); - - KRATOS_CATCH("") -} - -template -double UPwSmallStrainElement::CalculateFluidPressure(const ElementVariables& rVariables) -{ - KRATOS_TRY - - return inner_prod(rVariables.Np, rVariables.PressureVector); - - KRATOS_CATCH("") -} - template void UPwSmallStrainElement::CalculateRetentionResponse(ElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters, @@ -1764,17 +1552,13 @@ void UPwSmallStrainElement::CalculateRetentionResponse(ElementV { KRATOS_TRY - rVariables.FluidPressure = CalculateFluidPressure(rVariables); - SetRetentionParameters(rVariables, rRetentionParameters); + rRetentionParameters.SetFluidPressure(GeoTransportEquationUtilities::CalculateFluidPressure( + rVariables.Np, rVariables.PressureVector)); rVariables.DegreeOfSaturation = mRetentionLawVector[GPoint]->CalculateSaturation(rRetentionParameters); rVariables.DerivativeOfSaturation = mRetentionLawVector[GPoint]->CalculateDerivativeOfSaturation(rRetentionParameters); - rVariables.RelativePermeability = - mRetentionLawVector[GPoint]->CalculateRelativePermeability(rRetentionParameters); rVariables.BishopCoefficient = mRetentionLawVector[GPoint]->CalculateBishopCoefficient(rRetentionParameters); - rVariables.EffectiveSaturation = - mRetentionLawVector[GPoint]->CalculateEffectiveSaturation(rRetentionParameters); KRATOS_CATCH("") } @@ -1943,6 +1727,47 @@ Vector UPwSmallStrainElement::GetPressureSolutionVector() return result; } +template +void UPwSmallStrainElement::CalculateAnyOfMaterialResponse( + const std::vector& rDeformationGradients, + ConstitutiveLaw::Parameters& rConstitutiveParameters, + const Matrix& rNuContainer, + const GeometryType::ShapeFunctionsGradientsType& rDNu_DXContainer, + std::vector& rStrainVectors, + std::vector& rStressVectors, + std::vector& rConstitutiveMatrices) +{ + if (rStrainVectors.size() != rDeformationGradients.size()) { + rStrainVectors.resize(rDeformationGradients.size()); + std::fill(rStrainVectors.begin(), rStrainVectors.end(), + ZeroVector(this->GetStressStatePolicy().GetVoigtSize())); + } + if (rStressVectors.size() != rDeformationGradients.size()) { + rStressVectors.resize(rDeformationGradients.size()); + std::fill(rStressVectors.begin(), rStressVectors.end(), + ZeroVector(this->GetStressStatePolicy().GetVoigtSize())); + } + if (rConstitutiveMatrices.size() != rDeformationGradients.size()) { + rConstitutiveMatrices.resize(rDeformationGradients.size()); + std::fill(rConstitutiveMatrices.begin(), rConstitutiveMatrices.end(), + ZeroMatrix(this->GetStressStatePolicy().GetVoigtSize(), + this->GetStressStatePolicy().GetVoigtSize())); + } + + const auto determinants_of_deformation_gradients = + GeoMechanicsMathUtilities::CalculateDeterminants(rDeformationGradients); + + for (unsigned int GPoint = 0; GPoint < rDeformationGradients.size(); ++GPoint) { + ConstitutiveLawUtilities::SetConstitutiveParameters( + rConstitutiveParameters, rStrainVectors[GPoint], rConstitutiveMatrices[GPoint], + row(rNuContainer, GPoint), rDNu_DXContainer[GPoint], rDeformationGradients[GPoint], + determinants_of_deformation_gradients[GPoint]); + rConstitutiveParameters.SetStressVector(rStressVectors[GPoint]); + + mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(rConstitutiveParameters); + } +} + template class UPwSmallStrainElement<2, 3>; template class UPwSmallStrainElement<2, 4>; template class UPwSmallStrainElement<3, 4>; diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.hpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.hpp index 79d39cbfeec2..03a350c1e8f5 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_element.hpp @@ -124,10 +124,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa void PrintInfo(std::ostream& rOStream) const override { rOStream << Info(); } protected: - static constexpr SizeType VoigtSize = (TDim == N_DIM_3D ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); - static constexpr SizeType StressTensorSize = - (TDim == N_DIM_3D ? STRESS_TENSOR_SIZE_3D : STRESS_TENSOR_SIZE_2D); - struct ElementVariables { /// Properties variables bool IgnoreUndrained; @@ -138,7 +134,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa double SolidDensity; double Density; double Porosity; - double PermeabilityUpdateFactor; double BiotCoefficient; double BiotModulusInverse; @@ -179,12 +174,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa GeometryType::ShapeFunctionsGradientsType DN_DXContainer; /// Retention Law parameters - double FluidPressure; double DegreeOfSaturation; double DerivativeOfSaturation; double RelativePermeability; double BishopCoefficient; - double EffectiveSaturation; // needed for updated Lagrangian: double detJ; @@ -220,16 +213,8 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa virtual void InitializeElementVariables(ElementVariables& rVariables, const ProcessInfo& CurrentProcessInfo); - void SetConstitutiveParameters(ElementVariables& rVariables, ConstitutiveLaw::Parameters& rConstitutiveParameters); - - void SetRetentionParameters(const ElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters); - virtual void CalculateKinematics(ElementVariables& rVariables, unsigned int PointNumber); - void InitializeBiotCoefficients(ElementVariables& rVariables, bool hasBiotCoefficient = false); - - double CalculatePermeabilityUpdateFactor(const Vector& rStrainVector) const; - Matrix CalculateBMatrix(const Matrix& rDN_DX, const Vector& rN) const; std::vector CalculateBMatrices(const GeometryType::ShapeFunctionsGradientsType& rDN_DXContainer, const Matrix& rNContainer) const; @@ -242,9 +227,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa virtual void CalculateAndAddCompressibilityMatrix(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables); - virtual void CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, - const ElementVariables& rVariables); - virtual void CalculateAndAddRHS(VectorType& rRightHandSideVector, ElementVariables& rVariables, unsigned int GPoint); void CalculateAndAddStiffnessForce(VectorType& rRightHandSideVector, @@ -261,8 +243,8 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa array_1d& rPVector, const ElementVariables& rVariables) const; + [[nodiscard]] std::vector CalculateRelativePermeabilityValues(const std::vector& rFluidPressures) const; virtual void CalculateAndAddPermeabilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables); - virtual void CalculatePermeabilityFlow(BoundedMatrix& rPMatrix, array_1d& rPVector, const ElementVariables& rVariables) const; @@ -272,19 +254,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa array_1d& rPVector, const ElementVariables& rVariables) const; - double CalculateBulkModulus(const Matrix& ConstitutiveMatrix) const; - double CalculateBiotCoefficient(const ElementVariables& rVariables, bool hasBiotCoefficient) const; - - virtual Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const; - virtual Vector CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements) const; - virtual Vector CalculateStrain(const Matrix& rDeformationGradient, - const Matrix& rB, - const Vector& rDisplacements, - bool UseHenckyStrain) const; - std::vector CalculateStrains(const std::vector& rDeformationGradients, - const std::vector& rBs, - const Vector& rDisplacements, - bool UseHenckyStrain) const; + virtual Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const; Matrix CalculateDeformationGradient(unsigned int GPoint) const; std::vector CalculateDeformationGradients() const; @@ -293,8 +263,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa void InitializeNodalPorePressureVariables(ElementVariables& rVariables); void InitializeNodalVolumeAccelerationVariables(ElementVariables& rVariables); - void InitializeProperties(ElementVariables& rVariables); - double CalculateFluidPressure(const ElementVariables& rVariables); + void InitializeProperties(ElementVariables& rVariables); std::vector> CalculateFluidFluxes(const std::vector& rPermeabilityUpdateFactors, const ProcessInfo& rCurrentProcessInfo); @@ -302,6 +271,20 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainElement : public UPwBa RetentionLaw::Parameters& rRetentionParameters, unsigned int GPoint); + /// + /// \brief This function calculates the constitutive matrices, stresses and strains depending on the + /// constitutive parameters. Note that depending on the settings in the rConstitutiveParameters + /// the function could calculate the stress, the constitutive matrix, the strains, or a combination. + /// In our elements we generally always calculate the constitutive matrix and sometimes the stress. + /// + void CalculateAnyOfMaterialResponse(const std::vector& rDeformationGradients, + ConstitutiveLaw::Parameters& rConstitutiveParameters, + const Matrix& rNuContainer, + const GeometryType::ShapeFunctionsGradientsType& rDNu_DXContainer, + std::vector& rStrainVectors, + std::vector& rStressVectors, + std::vector& rConstitutiveMatrices); + void CalculateExtrapolationMatrix(BoundedMatrix& rExtrapolationMatrix); void ResetHydraulicDischarge(); diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.cpp index 218b6875c4a9..feda96d5a064 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.cpp @@ -13,6 +13,7 @@ // Application includes #include "custom_elements/U_Pw_small_strain_interface_element.hpp" +#include "custom_utilities/constitutive_law_utilities.hpp" #include "custom_utilities/transport_equation_utilities.hpp" #include @@ -172,8 +173,7 @@ void UPwSmallStrainInterfaceElement::CalculateMassMatrix(Matrix InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, Geom, Prop, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Defining necessary variables BoundedMatrix AuxDensityMatrix = ZeroMatrix(TDim, TNumNodes * TDim); @@ -252,8 +252,7 @@ void UPwSmallStrainInterfaceElement::InitializeSolutionStep(con unsigned int NumGPoints = mConstitutiveLawVector.size(); std::vector JointWidthContainer(NumGPoints); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -314,8 +313,7 @@ void UPwSmallStrainInterfaceElement::FinalizeSolutionStep(const unsigned int NumGPoints = mConstitutiveLawVector.size(); std::vector JointWidthContainer(NumGPoints); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -596,12 +594,13 @@ void UPwSmallStrainInterfaceElement::CalculateOnIntegrationPoin InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, rGeom, this->GetProperties(), rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); + // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { - Variables.FluidPressure = CalculateFluidPressure(Variables); - SetRetentionParameters(Variables, RetentionParameters); + Variables.FluidPressure = GeoTransportEquationUtilities::CalculateFluidPressure( + Variables.Np, Variables.PressureVector); + RetentionParameters.SetFluidPressure(Variables.FluidPressure); if (rVariable == DEGREE_OF_SATURATION) GPValues[GPoint] = mRetentionLawVector[GPoint]->CalculateSaturation(RetentionParameters); @@ -658,7 +657,9 @@ void UPwSmallStrainInterfaceElement::CalculateOnIntegrationPoin ConstitutiveParameters.Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); ConstitutiveParameters.Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Np, Variables.GradNpT, Variables.F, Variables.detF); // Auxiliary variables const double& MinimumJointWidth = rProp[MINIMUM_JOINT_WIDTH]; @@ -819,8 +820,7 @@ void UPwSmallStrainInterfaceElement::CalculateOnLobattoIntegrat InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, Geom, Prop, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -986,8 +986,7 @@ void UPwSmallStrainInterfaceElement::CalculateOnLobattoIntegrat InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, rGeom, rProp, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); Vector VoigtVector(mStressVector[0].size()); noalias(VoigtVector) = ZeroVector(VoigtVector.size()); @@ -999,8 +998,9 @@ void UPwSmallStrainInterfaceElement::CalculateOnLobattoIntegrat Vector TotalStressVector(mStressVector[0].size()); - // set Gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Np, Variables.GradNpT, Variables.F, Variables.detF); // Auxiliary variables const double& MinimumJointWidth = rProp[MINIMUM_JOINT_WIDTH]; @@ -1250,7 +1250,10 @@ void UPwSmallStrainInterfaceElement::CalculateMaterialStiffness // Element variables InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, Geom, Prop, CurrentProcessInfo); - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + + ConstitutiveLawUtilities::SetConstitutiveParameters(ConstitutiveParameters, Variables.StrainVector, + Variables.ConstitutiveMatrix, Variables.Np, + Variables.GradNpT, Variables.F, Variables.detF); // Auxiliary variables const double& MinimumJointWidth = Prop[MINIMUM_JOINT_WIDTH]; @@ -1324,7 +1327,10 @@ void UPwSmallStrainInterfaceElement::CalculateAll(MatrixType& r // Element variables InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, Geom, Prop, CurrentProcessInfo); - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + + ConstitutiveLawUtilities::SetConstitutiveParameters(ConstitutiveParameters, Variables.StrainVector, + Variables.ConstitutiveMatrix, Variables.Np, + Variables.GradNpT, Variables.F, Variables.detF); // Auxiliary variables const double& MinimumJointWidth = Prop[MINIMUM_JOINT_WIDTH]; @@ -1332,8 +1338,7 @@ void UPwSmallStrainInterfaceElement::CalculateAll(MatrixType& r array_1d RelDispVector; SFGradAuxVariables SFGradAuxVars; - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); @@ -1371,7 +1376,7 @@ void UPwSmallStrainInterfaceElement::CalculateAll(MatrixType& r ModifyInactiveElementStress(Variables.JointWidth, mStressVector[GPoint]); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); @@ -1447,22 +1452,6 @@ void UPwSmallStrainInterfaceElement::InitializeElementVariables KRATOS_CATCH("") } -template -void UPwSmallStrainInterfaceElement::SetConstitutiveParameters( - InterfaceElementVariables& rVariables, ConstitutiveLaw::Parameters& rConstitutiveParameters) -{ - KRATOS_TRY - - rConstitutiveParameters.SetStrainVector(rVariables.StrainVector); - rConstitutiveParameters.SetConstitutiveMatrix(rVariables.ConstitutiveMatrix); - rConstitutiveParameters.SetShapeFunctionsValues(rVariables.Np); - rConstitutiveParameters.SetShapeFunctionsDerivatives(rVariables.GradNpT); - rConstitutiveParameters.SetDeformationGradientF(rVariables.F); - rConstitutiveParameters.SetDeterminantF(rVariables.detF); - - KRATOS_CATCH("") -} - template <> void UPwSmallStrainInterfaceElement<2, 4>::CalculateRotationMatrix(BoundedMatrix& rRotationMatrix, const GeometryType& Geom) @@ -1923,7 +1912,7 @@ void UPwSmallStrainInterfaceElement::CalculateAndAddPermeabilit rVariables.PPMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.LocalPermeabilityMatrix, - rVariables.RelativePermeability, rVariables.JointWidth, rVariables.IntegrationCoefficient); + rVariables.RelativePermeability * rVariables.JointWidth, rVariables.IntegrationCoefficient); // Distribute permeability block matrix into the elemental matrix GeoElementUtilities::AssemblePPBlockMatrix(rLeftHandSideMatrix, rVariables.PPMatrix); @@ -2092,35 +2081,15 @@ void UPwSmallStrainInterfaceElement::CalculateAndAddFluidBodyFl KRATOS_CATCH("") } -template -void UPwSmallStrainInterfaceElement::SetRetentionParameters( - const InterfaceElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters) -{ - KRATOS_TRY - - rRetentionParameters.SetFluidPressure(rVariables.FluidPressure); - - KRATOS_CATCH("") -} - -template -double UPwSmallStrainInterfaceElement::CalculateFluidPressure(const InterfaceElementVariables& rVariables) -{ - KRATOS_TRY - - return inner_prod(rVariables.Np, rVariables.PressureVector); - - KRATOS_CATCH("") -} - template void UPwSmallStrainInterfaceElement::CalculateRetentionResponse( InterfaceElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters, unsigned int GPoint) { KRATOS_TRY - rVariables.FluidPressure = CalculateFluidPressure(rVariables); - SetRetentionParameters(rVariables, rRetentionParameters); + rVariables.FluidPressure = + GeoTransportEquationUtilities::CalculateFluidPressure(rVariables.Np, rVariables.PressureVector); + rRetentionParameters.SetFluidPressure(rVariables.FluidPressure); rVariables.DegreeOfSaturation = mRetentionLawVector[GPoint]->CalculateSaturation(rRetentionParameters); rVariables.DerivativeOfSaturation = diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.hpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.hpp index ea526388e7ba..13876cc9a960 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_interface_element.hpp @@ -281,11 +281,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainInterfaceElement template void InterpolateOutputValues(std::vector& rOutput, const std::vector& GPValues); - void SetRetentionParameters(const InterfaceElementVariables& rVariables, - RetentionLaw::Parameters& rRetentionParameters); - - double CalculateFluidPressure(const InterfaceElementVariables& rVariables); - double CalculateBulkModulus(const Matrix& ConstitutiveMatrix); void InitializeBiotCoefficients(InterfaceElementVariables& rVariables, const bool& hasBiotCoefficient = false); @@ -295,9 +290,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwSmallStrainInterfaceElement unsigned int GPoint); void CalculateSoilGamma(InterfaceElementVariables& rVariables); - - void SetConstitutiveParameters(InterfaceElementVariables& rVariables, - ConstitutiveLaw::Parameters& rConstitutiveParameters); Vector SetFullStressVector(const Vector& rStressVector); diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_link_interface_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_link_interface_element.cpp index 8147f29d51ba..3d9871c71beb 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_link_interface_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_small_strain_link_interface_element.cpp @@ -13,6 +13,7 @@ // Application includes #include "custom_elements/U_Pw_small_strain_link_interface_element.hpp" +#include "custom_utilities/constitutive_law_utilities.hpp" namespace Kratos { @@ -321,15 +322,17 @@ void UPwSmallStrainLinkInterfaceElement::CalculateAll(MatrixTyp // Element variables InterfaceElementVariables Variables; this->InitializeElementVariables(Variables, Geom, Prop, CurrentProcessInfo); - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + + ConstitutiveLawUtilities::SetConstitutiveParameters(ConstitutiveParameters, Variables.StrainVector, + Variables.ConstitutiveMatrix, Variables.Np, + Variables.GradNpT, Variables.F, Variables.detF); // Auxiliary variables const double& MinimumJointWidth = Prop[MINIMUM_JOINT_WIDTH]; array_1d RelDispVector; SFGradAuxVariables SFGradAuxVars; - // create general parametes of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.cpp index 93b137e8f687..6bf60d74208f 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.cpp @@ -15,6 +15,7 @@ // Project includes #include "custom_elements/U_Pw_updated_lagrangian_FIC_element.hpp" #include "custom_utilities/math_utilities.h" +#include "custom_utilities/transport_equation_utilities.hpp" #include "utilities/math_utils.h" namespace Kratos @@ -68,19 +69,23 @@ void UPwUpdatedLagrangianFICElement::CalculateAll(MatrixType& r FICElementVariables FICVariables; this->InitializeFICElementVariables(FICVariables, Variables.DN_DXContainer, Geom, Prop, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); - - const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto b_matrices = this->CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = + GeoTransportEquationUtilities::CalculateBiotCoefficients(constitutive_matrices, Prop); + const auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); // Computing in all integrations points for (IndexType GPoint = 0; GPoint < IntegrationPoints.size(); ++GPoint) { @@ -90,12 +95,9 @@ void UPwUpdatedLagrangianFICElement::CalculateAll(MatrixType& r // Cauchy strain: This needs to be investigated which strain measure should be used // In some references, e.g. Bathe, suggested to use Almansi strain measure - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; // Compute Np, Nu and BodyAcceleration GeoElementUtilities::CalculateNuMatrix(Variables.Nu, Variables.NContainer, GPoint); @@ -106,17 +108,16 @@ void UPwUpdatedLagrangianFICElement::CalculateAll(MatrixType& r // Compute ShapeFunctionsSecondOrderGradients this->CalculateShapeFunctionsSecondOrderGradients(FICVariables, Variables); - // Compute constitutive tensor and stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; // set shear modulus from stiffness matrix FICVariables.ShearModulus = CalculateShearModulus(Variables.ConstitutiveMatrix); - // calculate Bulk modulus from stiffness matrix - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.hpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.hpp index ff6a2371ab8a..0053cefbe994 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_FIC_element.hpp @@ -77,7 +77,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwUpdatedLagrangianFICElement using UPwBaseElement::CalculateDerivativesOnInitialConfiguration; using UPwBaseElement::mThisIntegrationMethod; using UPwSmallStrainFICElement::CalculateShearModulus; - using UPwSmallStrainElement::CalculateBulkModulus; using ElementVariables = typename UPwSmallStrainElement::ElementVariables; using FICElementVariables = typename UPwSmallStrainFICElement::FICElementVariables; diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.cpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.cpp index 607f1db1e7be..6e708af001bd 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.cpp @@ -15,6 +15,7 @@ // Project includes #include "custom_elements/U_Pw_updated_lagrangian_element.hpp" #include "custom_utilities/math_utilities.h" +#include "custom_utilities/transport_equation_utilities.hpp" #include "utilities/math_utils.h" namespace Kratos @@ -40,21 +41,6 @@ Element::Pointer UPwUpdatedLagrangianElement::Create(IndexType this->GetStressStatePolicy().Clone())); } -//---------------------------------------------------------------------------------------- -template -int UPwUpdatedLagrangianElement::Check(const ProcessInfo& rCurrentProcessInfo) const -{ - KRATOS_TRY - - // Base class checks for positive area and Id > 0 - // Verify generic variables - int ierr = UPwSmallStrainElement::Check(rCurrentProcessInfo); - - return ierr; - - KRATOS_CATCH(""); -} - //---------------------------------------------------------------------------------------- template void UPwUpdatedLagrangianElement::CalculateAll(MatrixType& rLeftHandSideMatrix, @@ -80,47 +66,46 @@ void UPwUpdatedLagrangianElement::CalculateAll(MatrixType& rLef ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); - const bool hasBiotCoefficient = this->GetProperties().Has(BIOT_COEFFICIENT); const auto b_matrices = this->CalculateBMatrices(Variables.DN_DXContainer, Variables.NContainer); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NContainer, Variables.DN_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); + const auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); - // Computing in all integrations points for (IndexType GPoint = 0; GPoint < IntegrationPoints.size(); ++GPoint) { - // Compute element kinematics B, F, GradNpT ... this->CalculateKinematics(Variables, GPoint); Variables.B = b_matrices[GPoint]; // Cauchy strain: This needs to be investigated which strain measure should be used // In some references, e.g. Bathe, suggested to use Almansi strain measure - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; // Compute Np, Nu and BodyAcceleration GeoElementUtilities::CalculateNuMatrix(Variables.Nu, Variables.NContainer, GPoint); GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - // Compute constitutive tensor and stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - // calculate Bulk modulus from stiffness matrix - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; diff --git a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.hpp b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.hpp index ce672b88b3ac..eeedc3d86ef3 100644 --- a/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/U_Pw_updated_lagrangian_element.hpp @@ -79,7 +79,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwUpdatedLagrangianElement using UPwBaseElement::mThisIntegrationMethod; using ElementVariables = typename UPwSmallStrainElement::ElementVariables; - using UPwSmallStrainElement::CalculateBulkModulus; /// Counted pointer of UPwUpdatedLagrangianElement KRATOS_CLASS_INTRUSIVE_POINTER_DEFINITION(UPwUpdatedLagrangianElement); @@ -119,8 +118,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UPwUpdatedLagrangianElement ~UPwUpdatedLagrangianElement() = default; - int Check(const ProcessInfo& rCurrentProcessInfo) const override; - /** * @brief Creates a new element * @param NewId The Id of the new created element diff --git a/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.cpp b/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.cpp index aaa27ec59aac..fa6b351181e1 100644 --- a/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.cpp @@ -65,4 +65,10 @@ Vector AxisymmetricStressState::CalculateGreenLagrangeStrain(const Matrix& rDefo "configurations.\n"; } +const Vector& AxisymmetricStressState::GetVoigtVector() const { return VoigtVector2D; } + +SizeType AxisymmetricStressState::GetVoigtSize() const { return GetVoigtSize2D(); } + +SizeType AxisymmetricStressState::GetStressTensorSize() const { return GetStressTensorSize2D(); } + } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.h b/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.h index a9e9fcce6ad6..41c189502060 100644 --- a/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.h +++ b/applications/GeoMechanicsApplication/custom_elements/axisymmetric_stress_state.h @@ -29,6 +29,9 @@ class AxisymmetricStressState : public StressStatePolicy const Geometry& rGeometry) const override; [[nodiscard]] Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const override; [[nodiscard]] std::unique_ptr Clone() const override; + [[nodiscard]] const Vector& GetVoigtVector() const override; + [[nodiscard]] SizeType GetVoigtSize() const override; + [[nodiscard]] SizeType GetStressTensorSize() const override; }; } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.cpp b/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.cpp index ed04dda03ba7..d5915fbfbc8b 100644 --- a/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.cpp @@ -61,4 +61,10 @@ Vector PlaneStrainStressState::ConvertStrainTensorToVector(const Matrix& rStrain return result; } +const Vector& PlaneStrainStressState::GetVoigtVector() const { return VoigtVector2D; } + +SizeType PlaneStrainStressState::GetVoigtSize() const { return GetVoigtSize2D(); } + +SizeType PlaneStrainStressState::GetStressTensorSize() const { return GetStressTensorSize2D(); } + } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.h b/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.h index 4b88e787066e..78c28e453a6b 100644 --- a/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.h +++ b/applications/GeoMechanicsApplication/custom_elements/plane_strain_stress_state.h @@ -28,6 +28,9 @@ class PlaneStrainStressState : public StressStatePolicy const Geometry& rGeometry) const override; [[nodiscard]] Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const override; [[nodiscard]] std::unique_ptr Clone() const override; + [[nodiscard]] const Vector& GetVoigtVector() const override; + [[nodiscard]] SizeType GetVoigtSize() const override; + [[nodiscard]] SizeType GetStressTensorSize() const override; private: [[nodiscard]] static Vector ConvertStrainTensorToVector(const Matrix& rStrainTensor); diff --git a/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.cpp b/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.cpp index 390a1d5b14c0..fa2525fe2b2d 100644 --- a/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.cpp @@ -20,6 +20,7 @@ // Application includes #include "custom_elements/small_strain_U_Pw_diff_order_element.hpp" +#include "custom_utilities/constitutive_law_utilities.hpp" #include "custom_utilities/dof_utilities.h" #include "custom_utilities/element_utilities.hpp" #include "custom_utilities/equation_of_motion_utilities.h" @@ -251,8 +252,7 @@ void SmallStrainUPwDiffOrderElement::Initialize(const ProcessInfo& rCurrentProce } // resize mStressVector: - const SizeType Dim = rGeom.WorkingSpaceDimension(); - const SizeType VoigtSize = (Dim == N_DIM_3D ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); + const SizeType VoigtSize = mpStressStatePolicy->GetVoigtSize(); if (mStressVector.size() != IntegrationPoints.size()) { mStressVector.resize(IntegrationPoints.size()); for (unsigned int i = 0; i < mStressVector.size(); ++i) { @@ -313,15 +313,15 @@ void SmallStrainUPwDiffOrderElement::InitializeSolutionStep(const ProcessInfo& r ConstitutiveParameters.Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); ConstitutiveParameters.Set(ConstitutiveLaw::INITIALIZE_MATERIAL_RESPONSE); // Note: this is for nonlocal damage - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); const auto determinants_of_deformation_gradients = GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + mpStressStatePolicy->GetVoigtSize()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mConstitutiveLawVector.size(); ++GPoint) { @@ -334,8 +334,9 @@ void SmallStrainUPwDiffOrderElement::InitializeSolutionStep(const ProcessInfo& r Variables.detF = determinants_of_deformation_gradients[GPoint]; Variables.StrainVector = strain_vectors[GPoint]; - // set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Nu, Variables.DNu_DX, Variables.F, Variables.detF); // compute constitutive tensor and/or stresses noalias(Variables.StressVector) = mStressVector[GPoint]; @@ -453,7 +454,7 @@ void SmallStrainUPwDiffOrderElement::CalculateMassMatrix(MatrixType& rMassMatrix const PropertiesType& r_prop = this->GetProperties(); const auto degrees_saturation = GeoTransportEquationUtilities::CalculateDegreesSaturation( - this->GetPressureSolutionVector(), Np_container, mRetentionLawVector, r_prop, rCurrentProcessInfo); + this->GetPressureSolutionVector(), Np_container, mRetentionLawVector, r_prop); const auto solid_densities = GeoTransportEquationUtilities::CalculateSoilDensities(degrees_saturation, r_prop); @@ -529,14 +530,15 @@ void SmallStrainUPwDiffOrderElement::FinalizeSolutionStep(const ProcessInfo& rCu ConstitutiveLaw::Parameters ConstitutiveParameters(GetGeometry(), GetProperties(), rCurrentProcessInfo); ConstitutiveParameters.GetOptions().Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); + const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); const auto determinants_of_deformation_gradients = GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + mpStressStatePolicy->GetVoigtSize()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mConstitutiveLawVector.size(); ++GPoint) { @@ -548,8 +550,10 @@ void SmallStrainUPwDiffOrderElement::FinalizeSolutionStep(const ProcessInfo& rCu Variables.F = deformation_gradients[GPoint]; Variables.detF = determinants_of_deformation_gradients[GPoint]; Variables.StrainVector = strain_vectors[GPoint]; - // set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); + + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, Variables.StrainVector, Variables.ConstitutiveMatrix, + Variables.Nu, Variables.DNu_DX, Variables.F, Variables.detF); // compute constitutive tensor and/or stresses noalias(Variables.StressVector) = mStressVector[GPoint]; @@ -909,27 +913,26 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mRetentionLawVector.size(); ++GPoint) { // Compute Np, GradNpT, B and StrainVector this->CalculateKinematics(Variables, GPoint); - Variables.FluidPressure = CalculateFluidPressure(Variables); - SetRetentionParameters(Variables, RetentionParameters); + RetentionParameters.SetFluidPressure(GeoTransportEquationUtilities::CalculateFluidPressure( + Variables.Np, Variables.PressureVector)); if (rVariable == DEGREE_OF_SATURATION) rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateSaturation(RetentionParameters); - if (rVariable == EFFECTIVE_SATURATION) + else if (rVariable == EFFECTIVE_SATURATION) rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateEffectiveSaturation(RetentionParameters); - if (rVariable == BISHOP_COEFFICIENT) + else if (rVariable == BISHOP_COEFFICIENT) rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateBishopCoefficient(RetentionParameters); - if (rVariable == DERIVATIVE_OF_SATURATION) + else if (rVariable == DERIVATIVE_OF_SATURATION) rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateDerivativeOfSaturation(RetentionParameters); - if (rVariable == RELATIVE_PERMEABILITY) + else if (rVariable == RELATIVE_PERMEABILITY) rOutput[GPoint] = mRetentionLawVector[GPoint]->CalculateRelativePermeability(RetentionParameters); } @@ -998,12 +1001,19 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + const auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, mpStressStatePolicy->GetVoigtSize()); + auto relative_permeability_values = + CalculateRelativePermeabilityValues(GeoTransportEquationUtilities::CalculateFluidPressures( + Variables.NpContainer, Variables.PressureVector)); + const auto permeability_update_factors = + GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors(strain_vectors, GetProperties()); + std::transform(relative_permeability_values.cbegin(), relative_permeability_values.cend(), + permeability_update_factors.cbegin(), relative_permeability_values.begin(), + std::multiplies<>{}); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mConstitutiveLawVector.size(); ++GPoint) { @@ -1022,16 +1032,11 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable BodyAcceleration[idim] += Variables.Nu[i] * Variables.BodyAcceleration[Index++]; } - CalculateFluidPressure(Variables); - SetRetentionParameters(Variables, RetentionParameters); - - const double RelativePermeability = - mRetentionLawVector[GPoint]->CalculateRelativePermeability(RetentionParameters); + const auto relative_permeability = relative_permeability_values[GPoint]; // Compute strain, need to update porosity Variables.F = deformation_gradients[GPoint]; Variables.StrainVector = strain_vectors[GPoint]; - Variables.PermeabilityUpdateFactor = this->CalculatePermeabilityUpdateFactor(Variables.StrainVector); Vector GradPressureTerm(Dim); noalias(GradPressureTerm) = prod(trans(Variables.DNp_DX), Variables.PressureVector); @@ -1040,8 +1045,7 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable Vector AuxFluidFlux = ZeroVector(Dim); AuxFluidFlux = PORE_PRESSURE_SIGN_FACTOR * Variables.DynamicViscosityInverse * - RelativePermeability * Variables.PermeabilityUpdateFactor * - prod(Variables.IntrinsicPermeability, GradPressureTerm); + relative_permeability * prod(Variables.IntrinsicPermeability, GradPressureTerm); Vector FluidFlux = ZeroVector(3); for (unsigned int idim = 0; idim < Dim; ++idim) @@ -1063,10 +1067,10 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable KRATOS_TRY const GeometryType& rGeom = GetGeometry(); - const SizeType& IntegrationPointsNumber = rGeom.IntegrationPointsNumber(this->GetIntegrationMethod()); - const SizeType Dim = rGeom.WorkingSpaceDimension(); - if (rOutput.size() != IntegrationPointsNumber) rOutput.resize(IntegrationPointsNumber); + if (const SizeType& IntegrationPointsNumber = rGeom.IntegrationPointsNumber(this->GetIntegrationMethod()); + rOutput.size() != IntegrationPointsNumber) + rOutput.resize(IntegrationPointsNumber); if (rVariable == CAUCHY_STRESS_VECTOR) { // Loop over integration points @@ -1094,7 +1098,8 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable Variables.B = this->CalculateBMatrix(Variables.DNu_DXInitialConfiguration, Variables.Nu); // Compute infinitesimal strain - Variables.StrainVector = this->CalculateCauchyStrain(Variables.B, Variables.DisplacementVector); + Variables.StrainVector = + StressStrainUtilities::CalculateCauchyStrain(Variables.B, Variables.DisplacementVector); if (rOutput[GPoint].size() != Variables.StrainVector.size()) rOutput[GPoint].resize(Variables.StrainVector.size(), false); @@ -1107,8 +1112,9 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable this->InitializeElementVariables(Variables, rCurrentProcessInfo); const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); - rOutput = CalculateStrains(deformation_gradients, b_matrices, Variables.DisplacementVector, - Variables.UseHenckyStrain); + rOutput = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, mpStressStatePolicy->GetVoigtSize()); } else if (rVariable == TOTAL_STRESS_VECTOR) { // Definition of variables ElementVariables Variables; @@ -1119,59 +1125,32 @@ void SmallStrainUPwDiffOrderElement::CalculateOnIntegrationPoints(const Variable ConstitutiveParameters.GetOptions().Set(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR); ConstitutiveParameters.GetOptions().Set(ConstitutiveLaw::USE_ELEMENT_PROVIDED_STRAIN); - const PropertiesType& rProp = this->GetProperties(); - - const SizeType VoigtSize = mStressVector[0].size(); - Vector VoigtVector = ZeroVector(VoigtSize); - const SizeType StressTensorSize = (Dim == N_DIM_3D ? STRESS_TENSOR_SIZE_3D : STRESS_TENSOR_SIZE_2D); - for (unsigned int i = 0; i < StressTensorSize; ++i) - VoigtVector[i] = 1.0; + const Vector& VoigtVector = mpStressStatePolicy->GetVoigtVector(); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); - - const bool hasBiotCoefficient = rProp.Has(BIOT_COEFFICIENT); - - Vector TotalStressVector(mStressVector[0].size()); + RetentionLaw::Parameters RetentionParameters(GetProperties()); const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, + Variables.UseHenckyStrain, mpStressStatePolicy->GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NuContainer, Variables.DNu_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); - // Loop over integration points for (unsigned int GPoint = 0; GPoint < mConstitutiveLawVector.size(); ++GPoint) { - // compute element kinematics (Np, gradNpT, |J|, B, strains) this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // compute constitutive tensor and/or stresses - noalias(Variables.StressVector) = mStressVector[GPoint]; - ConstitutiveParameters.SetStressVector(Variables.StressVector); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - - Variables.BiotCoefficient = CalculateBiotCoefficient(Variables, hasBiotCoefficient); - - this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); - - noalias(TotalStressVector) = mStressVector[GPoint]; - noalias(TotalStressVector) += PORE_PRESSURE_SIGN_FACTOR * Variables.BiotCoefficient * - Variables.BishopCoefficient * Variables.FluidPressure * VoigtVector; - - if (rOutput[GPoint].size() != TotalStressVector.size()) { - rOutput[GPoint].resize(TotalStressVector.size(), false); - } - rOutput[GPoint] = TotalStressVector; + const auto fluid_pressure = GeoTransportEquationUtilities::CalculateFluidPressure( + Variables.Np, Variables.PressureVector); + RetentionParameters.SetFluidPressure(fluid_pressure); + const auto bishop_coefficient = + mRetentionLawVector[GPoint]->CalculateBishopCoefficient(RetentionParameters); + + rOutput[GPoint] = mStressVector[GPoint] + PORE_PRESSURE_SIGN_FACTOR * biot_coefficients[GPoint] * + bishop_coefficient * fluid_pressure * VoigtVector; } } else { for (unsigned int i = 0; i < mConstitutiveLawVector.size(); ++i) @@ -1273,45 +1252,48 @@ void SmallStrainUPwDiffOrderElement::CalculateAll(MatrixType& rLeftHandSi if (CalculateResidualVectorFlag) ConstitutiveParameters.GetOptions().Set(ConstitutiveLaw::COMPUTE_STRESS); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(rProp, rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(rProp); // Loop over integration points const GeometryType::IntegrationPointsArrayType& IntegrationPoints = rGeom.IntegrationPoints(this->GetIntegrationMethod()); - const bool hasBiotCoefficient = rProp.Has(BIOT_COEFFICIENT); const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); const auto integration_coefficients = CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJuContainer); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + mpStressStatePolicy->GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NuContainer, Variables.DNu_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); + auto relative_permeability_values = + CalculateRelativePermeabilityValues(GeoTransportEquationUtilities::CalculateFluidPressures( + Variables.NpContainer, Variables.PressureVector)); + const auto permeability_update_factors = + GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors(strain_vectors, GetProperties()); + std::transform(relative_permeability_values.cbegin(), relative_permeability_values.cend(), + permeability_update_factors.cbegin(), relative_permeability_values.begin(), + std::multiplies<>{}); for (unsigned int GPoint = 0; GPoint < IntegrationPoints.size(); ++GPoint) { - // compute element kinematics (Np, gradNpT, |J|, B, strains) this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // compute constitutive tensor and/or stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); + Variables.B = b_matrices[GPoint]; + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); - Variables.PermeabilityUpdateFactor = this->CalculatePermeabilityUpdateFactor(Variables.StrainVector); - + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; Variables.IntegrationCoefficientInitialConfiguration = this->CalculateIntegrationCoefficient( @@ -1350,46 +1332,20 @@ void SmallStrainUPwDiffOrderElement::CalculateMaterialStiffnessMatrix(MatrixType const auto b_matrices = CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); - const auto strain_vectors = CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); - - for (unsigned int GPoint = 0; GPoint < IntegrationPoints.size(); ++GPoint) { - // compute element kinematics (Np, gradNpT, |J|, B, strains) - this->CalculateKinematics(Variables, GPoint); - Variables.B = b_matrices[GPoint]; - - // Compute infinitesimal strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutive law parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // compute constitutive tensor and/or stresses - noalias(Variables.StressVector) = mStressVector[GPoint]; - ConstitutiveParameters.SetStressVector(Variables.StressVector); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); - - // calculating weighting coefficient for integration - Variables.IntegrationCoefficient = - this->CalculateIntegrationCoefficient(IntegrationPoints[GPoint], Variables.detJ); - - // Contributions of material stiffness to the left hand side - this->CalculateAndAddStiffnessMatrix(rStiffnessMatrix, Variables); - } + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + mpStressStatePolicy->GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NuContainer, Variables.DNu_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto integration_coefficients = + CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJuContainer); - KRATOS_CATCH("") -} + const auto stiffness_matrix = GeoEquationOfMotionUtilities::CalculateStiffnessMatrix( + b_matrices, constitutive_matrices, integration_coefficients); -double SmallStrainUPwDiffOrderElement::CalculateBulkModulus(const Matrix& ConstitutiveMatrix) const -{ - KRATOS_TRY - - const SizeType IndexG = ConstitutiveMatrix.size1() - 1; - return ConstitutiveMatrix(0, 0) - (4.0 / 3.0) * ConstitutiveMatrix(IndexG, IndexG); + GeoElementUtilities::AssembleUUBlockMatrix(rStiffnessMatrix, stiffness_matrix); KRATOS_CATCH("") } @@ -1459,7 +1415,7 @@ void SmallStrainUPwDiffOrderElement::InitializeElementVariables(ElementVariables } // Variables computed at each integration point - const SizeType VoigtSize = (Dim == 3 ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); + const SizeType VoigtSize = mpStressStatePolicy->GetVoigtSize(); rVariables.B.resize(VoigtSize, NumUNodes * Dim, false); noalias(rVariables.B) = ZeroMatrix(VoigtSize, NumUNodes * Dim); @@ -1485,15 +1441,11 @@ void SmallStrainUPwDiffOrderElement::InitializeElementVariables(ElementVariables rVariables.DtPressureCoefficient = rCurrentProcessInfo[DT_PRESSURE_COEFFICIENT]; // Retention law - rVariables.FluidPressure = 0.0; rVariables.DegreeOfSaturation = 1.0; rVariables.DerivativeOfSaturation = 0.0; rVariables.RelativePermeability = 1.0; rVariables.BishopCoefficient = 1.0; - // permeability change - rVariables.PermeabilityUpdateFactor = 1.0; - KRATOS_CATCH("") } @@ -1543,66 +1495,6 @@ void SmallStrainUPwDiffOrderElement::InitializeNodalVariables(ElementVariables& KRATOS_CATCH("") } -double SmallStrainUPwDiffOrderElement::CalculateBiotCoefficient(const ElementVariables& rVariables, - const bool& hasBiotCoefficient) const -{ - KRATOS_TRY - - const PropertiesType& rProp = this->GetProperties(); - - // Properties variables - if (hasBiotCoefficient) { - return rProp[BIOT_COEFFICIENT]; - } else { - // calculate Bulk modulus from stiffness matrix - return 1.0 - CalculateBulkModulus(rVariables.ConstitutiveMatrix) / rProp[BULK_MODULUS_SOLID]; - } - - KRATOS_CATCH("") -} - -void SmallStrainUPwDiffOrderElement::InitializeBiotCoefficients(ElementVariables& rVariables, - const bool& hasBiotCoefficient) -{ - KRATOS_TRY - - const PropertiesType& rProp = this->GetProperties(); - - rVariables.BiotCoefficient = CalculateBiotCoefficient(rVariables, hasBiotCoefficient); - - if (rProp[IGNORE_UNDRAINED]) { - rVariables.BiotModulusInverse = - (rVariables.BiotCoefficient - rProp[POROSITY]) / rProp[BULK_MODULUS_SOLID] + rProp[POROSITY] / TINY; - } else { - rVariables.BiotModulusInverse = - (rVariables.BiotCoefficient - rProp[POROSITY]) / rProp[BULK_MODULUS_SOLID] + - rProp[POROSITY] / rProp[BULK_MODULUS_FLUID]; - } - - rVariables.BiotModulusInverse *= rVariables.DegreeOfSaturation; - rVariables.BiotModulusInverse -= rVariables.DerivativeOfSaturation * rProp[POROSITY]; - - KRATOS_CATCH("") -} - -double SmallStrainUPwDiffOrderElement::CalculatePermeabilityUpdateFactor(const Vector& rStrainVector) const -{ - KRATOS_TRY - - if (const auto& r_prop = this->GetProperties(); r_prop[PERMEABILITY_CHANGE_INVERSE_FACTOR] > 0.0) { - const double InverseCK = r_prop[PERMEABILITY_CHANGE_INVERSE_FACTOR]; - const double epsV = StressStrainUtilities::CalculateTrace(rStrainVector); - const double ePrevious = r_prop[POROSITY] / (1.0 - r_prop[POROSITY]); - const double eCurrent = (1.0 + ePrevious) * std::exp(epsV) - 1.0; - const double permLog10 = (eCurrent - ePrevious) * InverseCK; - return std::pow(10.0, permLog10); - } - - return 1.0; - - KRATOS_CATCH("") -} - void SmallStrainUPwDiffOrderElement::InitializeProperties(ElementVariables& rVariables) { KRATOS_TRY @@ -1692,24 +1584,6 @@ std::vector SmallStrainUPwDiffOrderElement::CalculateBMatrices( return result; } -void SmallStrainUPwDiffOrderElement::SetConstitutiveParameters(ElementVariables& rVariables, - ConstitutiveLaw::Parameters& rConstitutiveParameters) const -{ - KRATOS_TRY - - rConstitutiveParameters.SetStrainVector(rVariables.StrainVector); - rConstitutiveParameters.SetConstitutiveMatrix(rVariables.ConstitutiveMatrix); - - // Needed parameters for consistency with the general constitutive law - rConstitutiveParameters.SetShapeFunctionsDerivatives(rVariables.DNu_DX); - rConstitutiveParameters.SetShapeFunctionsValues(rVariables.Nu); - - rConstitutiveParameters.SetDeterminantF(rVariables.detF); - rConstitutiveParameters.SetDeformationGradientF(rVariables.F); - - KRATOS_CATCH("") -} - double SmallStrainUPwDiffOrderElement::CalculateIntegrationCoefficient(const GeometryType::IntegrationPointType& rIntegrationPoint, double detJ) const { @@ -1736,41 +1610,35 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddLHS(MatrixType& rLeftHandSid if (!rVariables.IgnoreUndrained) { this->CalculateAndAddCouplingMatrix(rLeftHandSideMatrix, rVariables); - this->CalculateAndAddPermeabilityMatrix(rLeftHandSideMatrix, rVariables); + + const auto permeability_matrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( + rVariables.DNp_DX, rVariables.DynamicViscosityInverse, rVariables.IntrinsicPermeability, + rVariables.RelativePermeability, rVariables.IntegrationCoefficient); + GeoElementUtilities::AssemblePPBlockMatrix(rLeftHandSideMatrix, permeability_matrix); } KRATOS_CATCH("") } void SmallStrainUPwDiffOrderElement::CalculateAndAddStiffnessMatrix(MatrixType& rLeftHandSideMatrix, - ElementVariables& rVariables) const + const ElementVariables& rVariables) const { KRATOS_TRY - Matrix StiffnessMatrix = - prod(trans(rVariables.B), Matrix(prod(rVariables.ConstitutiveMatrix, rVariables.B))) * - rVariables.IntegrationCoefficient; + const auto stiffness_matrix = GeoEquationOfMotionUtilities::CalculateStiffnessMatrixGPoint( + rVariables.B, rVariables.ConstitutiveMatrix, rVariables.IntegrationCoefficient); - // Distribute stiffness block matrix into the elemental matrix - GeoElementUtilities::AssembleUUBlockMatrix(rLeftHandSideMatrix, StiffnessMatrix); + GeoElementUtilities::AssembleUUBlockMatrix(rLeftHandSideMatrix, stiffness_matrix); KRATOS_CATCH("") } void SmallStrainUPwDiffOrderElement::CalculateAndAddCouplingMatrix(MatrixType& rLeftHandSideMatrix, - const ElementVariables& rVariables) + const ElementVariables& rVariables) const { KRATOS_TRY - const GeometryType& rGeom = GetGeometry(); - const SizeType Dim = rGeom.WorkingSpaceDimension(); - const SizeType VoigtSize = (Dim == N_DIM_3D ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); - const SizeType StressTensorSize = (Dim == N_DIM_3D ? STRESS_TENSOR_SIZE_3D : STRESS_TENSOR_SIZE_2D); - - Vector VoigtVector = ZeroVector(VoigtSize); - - for (unsigned int i = 0; i < StressTensorSize; ++i) - VoigtVector[i] = 1.0; + const Vector& VoigtVector = mpStressStatePolicy->GetVoigtVector(); Matrix CouplingMatrix = GeoTransportEquationUtilities::CalculateCouplingMatrix( rVariables.B, VoigtVector, rVariables.Np, rVariables.BiotCoefficient, @@ -1806,21 +1674,6 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddCompressibilityMatrix(Matrix KRATOS_CATCH("") } -void SmallStrainUPwDiffOrderElement::CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, - const ElementVariables& rVariables) const -{ - KRATOS_TRY - - Matrix PermeabilityMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( - rVariables.DNp_DX, rVariables.DynamicViscosityInverse, rVariables.IntrinsicPermeability, - rVariables.RelativePermeability, rVariables.PermeabilityUpdateFactor, rVariables.IntegrationCoefficient); - - // Distribute permeability block matrix into the elemental matrix - GeoElementUtilities::AssemblePPBlockMatrix(rLeftHandSideMatrix, PermeabilityMatrix); - - KRATOS_CATCH("") -} - void SmallStrainUPwDiffOrderElement::CalculateAndAddRHS(VectorType& rRightHandSideVector, ElementVariables& rVariables, unsigned int GPoint) @@ -1868,7 +1721,7 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddMixBodyForce(VectorType& rRi const SizeType Dim = rGeom.WorkingSpaceDimension(); const SizeType NumUNodes = rGeom.PointsNumber(); - rVariables.Density = GeoTransportEquationUtilities::CalculateSoilDensity( + const auto soil_density = GeoTransportEquationUtilities::CalculateSoilDensity( rVariables.DegreeOfSaturation, this->GetProperties()); Vector BodyAcceleration = ZeroVector(Dim); @@ -1882,9 +1735,8 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddMixBodyForce(VectorType& rRi for (SizeType i = 0; i < NumUNodes; ++i) { Index = i * Dim; for (SizeType idim = 0; idim < Dim; ++idim) { - rRightHandSideVector[Index + idim] += - rVariables.Nu[i] * rVariables.Density * BodyAcceleration[idim] * - rVariables.IntegrationCoefficientInitialConfiguration; + rRightHandSideVector[Index + idim] += rVariables.Nu[i] * soil_density * BodyAcceleration[idim] * + rVariables.IntegrationCoefficientInitialConfiguration; } } @@ -1892,18 +1744,11 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddMixBodyForce(VectorType& rRi } void SmallStrainUPwDiffOrderElement::CalculateAndAddCouplingTerms(VectorType& rRightHandSideVector, - ElementVariables& rVariables) + ElementVariables& rVariables) const { KRATOS_TRY - const GeometryType& rGeom = GetGeometry(); - const SizeType Dim = rGeom.WorkingSpaceDimension(); - const SizeType VoigtSize = (Dim == N_DIM_3D ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); - const SizeType StressTensorSize = (Dim == N_DIM_3D ? STRESS_TENSOR_SIZE_3D : STRESS_TENSOR_SIZE_2D); - - Vector VoigtVector = ZeroVector(VoigtSize); - for (SizeType idim = 0; idim < StressTensorSize; ++idim) - VoigtVector[idim] = 1.0; + const Vector& VoigtVector = mpStressStatePolicy->GetVoigtVector(); Matrix CouplingMatrix = (-1.0) * GeoTransportEquationUtilities::CalculateCouplingMatrix( rVariables.B, VoigtVector, rVariables.Np, rVariables.BiotCoefficient, @@ -1942,14 +1787,28 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddCompressibilityFlow(VectorTy KRATOS_CATCH("") } +std::vector SmallStrainUPwDiffOrderElement::CalculateRelativePermeabilityValues(const std::vector& rFluidPressures) const +{ + KRATOS_ERROR_IF_NOT(rFluidPressures.size() == mRetentionLawVector.size()); + + auto retention_law_params = RetentionLaw::Parameters{this->GetProperties()}; + + auto result = std::vector{}; + std::transform(mRetentionLawVector.begin(), mRetentionLawVector.end(), rFluidPressures.begin(), + std::back_inserter(result), [&retention_law_params](auto pRetentionLaw, auto FluidPressure) { + retention_law_params.SetFluidPressure(FluidPressure); + return pRetentionLaw->CalculateRelativePermeability(retention_law_params); + }); + return result; +} + void SmallStrainUPwDiffOrderElement::CalculateAndAddPermeabilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) const { KRATOS_TRY Matrix PermeabilityMatrix = - -PORE_PRESSURE_SIGN_FACTOR * rVariables.DynamicViscosityInverse * - rVariables.RelativePermeability * rVariables.PermeabilityUpdateFactor * + -PORE_PRESSURE_SIGN_FACTOR * rVariables.DynamicViscosityInverse * rVariables.RelativePermeability * prod(rVariables.DNp_DX, Matrix(prod(rVariables.IntrinsicPermeability, trans(rVariables.DNp_DX)))) * rVariables.IntegrationCoefficient; @@ -1966,10 +1825,9 @@ void SmallStrainUPwDiffOrderElement::CalculateAndAddFluidBodyFlow(VectorType& rR { KRATOS_TRY - Matrix GradNpTPerm = rVariables.DynamicViscosityInverse * GetProperties()[DENSITY_WATER] * - rVariables.RelativePermeability * rVariables.PermeabilityUpdateFactor * - prod(rVariables.DNp_DX, rVariables.IntrinsicPermeability) * - rVariables.IntegrationCoefficient; + Matrix GradNpTPerm = + rVariables.DynamicViscosityInverse * GetProperties()[DENSITY_WATER] * rVariables.RelativePermeability * + prod(rVariables.DNp_DX, rVariables.IntrinsicPermeability) * rVariables.IntegrationCoefficient; const GeometryType& rGeom = GetGeometry(); const SizeType Dim = rGeom.WorkingSpaceDimension(); @@ -2019,40 +1877,6 @@ GeometryData::IntegrationMethod SmallStrainUPwDiffOrderElement::GetIntegrationMe return GI_GAUSS; } -std::vector SmallStrainUPwDiffOrderElement::CalculateStrains(const std::vector& rDeformationGradients, - const std::vector& rBs, - const Vector& rDisplacements, - bool UseHenckyStrain) const -{ - std::vector result; - std::transform( - rDeformationGradients.begin(), rDeformationGradients.end(), rBs.begin(), std::back_inserter(result), - [this, &rDisplacements, UseHenckyStrain](const auto& rDeformationGradient, const auto& rB) { - return CalculateStrain(rDeformationGradient, rB, rDisplacements, UseHenckyStrain); - }); - - return result; -} - -Vector SmallStrainUPwDiffOrderElement::CalculateStrain(const Matrix& rDeformationGradient, - const Matrix& rB, - const Vector& rDisplacements, - bool UseHenckyStrain) const -{ - if (UseHenckyStrain) { - const SizeType Dim = GetGeometry().WorkingSpaceDimension(); - const SizeType VoigtSize = (Dim == N_DIM_3D ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN); - return StressStrainUtilities::CalculateHenckyStrain(rDeformationGradient, VoigtSize); - } - - return this->CalculateCauchyStrain(rB, rDisplacements); -} - -Vector SmallStrainUPwDiffOrderElement::CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements) const -{ - return prod(rB, rDisplacements); -} - Vector SmallStrainUPwDiffOrderElement::CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const { return mpStressStatePolicy->CalculateGreenLagrangeStrain(rDeformationGradient); @@ -2113,39 +1937,18 @@ void SmallStrainUPwDiffOrderElement::CalculateJacobianOnCurrentConfiguration(dou KRATOS_CATCH("") } -double SmallStrainUPwDiffOrderElement::CalculateFluidPressure(const ElementVariables& rVariables) const -{ - KRATOS_TRY - - return inner_prod(rVariables.Np, rVariables.PressureVector); - - KRATOS_CATCH("") -} - -void SmallStrainUPwDiffOrderElement::SetRetentionParameters(const ElementVariables& rVariables, - RetentionLaw::Parameters& rRetentionParameters) const -{ - KRATOS_TRY - - rRetentionParameters.SetFluidPressure(rVariables.FluidPressure); - - KRATOS_CATCH("") -} - void SmallStrainUPwDiffOrderElement::CalculateRetentionResponse(ElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters, unsigned int GPoint) { KRATOS_TRY - rVariables.FluidPressure = CalculateFluidPressure(rVariables); - SetRetentionParameters(rVariables, rRetentionParameters); + rRetentionParameters.SetFluidPressure(GeoTransportEquationUtilities::CalculateFluidPressure( + rVariables.Np, rVariables.PressureVector)); rVariables.DegreeOfSaturation = mRetentionLawVector[GPoint]->CalculateSaturation(rRetentionParameters); rVariables.DerivativeOfSaturation = mRetentionLawVector[GPoint]->CalculateDerivativeOfSaturation(rRetentionParameters); - rVariables.RelativePermeability = - mRetentionLawVector[GPoint]->CalculateRelativePermeability(rRetentionParameters); rVariables.BishopCoefficient = mRetentionLawVector[GPoint]->CalculateBishopCoefficient(rRetentionParameters); KRATOS_CATCH("") @@ -2171,4 +1974,43 @@ Vector SmallStrainUPwDiffOrderElement::GetPressureSolutionVector() return result; } -} // Namespace Kratos \ No newline at end of file +void SmallStrainUPwDiffOrderElement::CalculateAnyOfMaterialResponse( + const std::vector& rDeformationGradients, + ConstitutiveLaw::Parameters& rConstitutiveParameters, + const Matrix& rNuContainer, + const GeometryType::ShapeFunctionsGradientsType& rDNu_DXContainer, + std::vector& rStrainVectors, + std::vector& rStressVectors, + std::vector& rConstitutiveMatrices) +{ + const SizeType voigt_size = + GetGeometry().WorkingSpaceDimension() == 3 ? VOIGT_SIZE_3D : VOIGT_SIZE_2D_PLANE_STRAIN; + + if (rStrainVectors.size() != rDeformationGradients.size()) { + rStrainVectors.resize(rDeformationGradients.size()); + std::fill(rStrainVectors.begin(), rStrainVectors.end(), ZeroVector(voigt_size)); + } + if (rStressVectors.size() != rDeformationGradients.size()) { + rStressVectors.resize(rDeformationGradients.size()); + std::fill(rStressVectors.begin(), rStressVectors.end(), ZeroVector(voigt_size)); + } + if (rConstitutiveMatrices.size() != rDeformationGradients.size()) { + rConstitutiveMatrices.resize(rDeformationGradients.size()); + std::fill(rConstitutiveMatrices.begin(), rConstitutiveMatrices.end(), ZeroMatrix(voigt_size, voigt_size)); + } + + const auto determinants_of_deformation_gradients = + GeoMechanicsMathUtilities::CalculateDeterminants(rDeformationGradients); + + for (unsigned int GPoint = 0; GPoint < rDeformationGradients.size(); ++GPoint) { + ConstitutiveLawUtilities::SetConstitutiveParameters( + rConstitutiveParameters, rStrainVectors[GPoint], rConstitutiveMatrices[GPoint], + row(rNuContainer, GPoint), rDNu_DXContainer[GPoint], rDeformationGradients[GPoint], + determinants_of_deformation_gradients[GPoint]); + rConstitutiveParameters.SetStressVector(rStressVectors[GPoint]); + + mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(rConstitutiveParameters); + } +} + +} // Namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.hpp b/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.hpp index d048274567b8..fd0c3e314539 100644 --- a/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/small_strain_U_Pw_diff_order_element.hpp @@ -193,12 +193,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SmallStrainUPwDiffOrderElement : pub Vector PressureDtVector; /// Retention Law parameters - double FluidPressure; double DegreeOfSaturation; double DerivativeOfSaturation; double RelativePermeability; double BishopCoefficient; - double Density; // Properties and processinfo variables bool IgnoreUndrained; @@ -206,7 +204,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SmallStrainUPwDiffOrderElement : pub bool ConsiderGeometricStiffness; // stress/flow variables - double PermeabilityUpdateFactor; double BiotCoefficient; double BiotModulusInverse; double DynamicViscosityInverse; @@ -240,18 +237,11 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SmallStrainUPwDiffOrderElement : pub void InitializeProperties(ElementVariables& rVariables); - void InitializeBiotCoefficients(ElementVariables& rVariables, const bool& hasBiotCoefficient = false); - - double CalculatePermeabilityUpdateFactor(const Vector& rStrainVector) const; - virtual void CalculateKinematics(ElementVariables& rVariables, unsigned int GPoint); void CalculateDerivativesOnInitialConfiguration( double& detJ, Matrix& J0, Matrix& InvJ0, Matrix& DN_DX, unsigned int PointNumber) const; - void SetConstitutiveParameters(ElementVariables& rVariables, - ConstitutiveLaw::Parameters& rConstitutiveParameters) const; - double CalculateIntegrationCoefficient(const GeometryType::IntegrationPointType& rIntegrationPoint, double detJ) const; std::vector CalculateIntegrationCoefficients(const GeometryType::IntegrationPointsArrayType& rIntegrationPoints, @@ -259,14 +249,12 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SmallStrainUPwDiffOrderElement : pub void CalculateAndAddLHS(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables); - void CalculateAndAddStiffnessMatrix(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables) const; + void CalculateAndAddStiffnessMatrix(MatrixType& rLeftHandSideMatrix, const ElementVariables& rVariables) const; - void CalculateAndAddCouplingMatrix(MatrixType& rLeftHandSideMatrix, const ElementVariables& rVariables); + void CalculateAndAddCouplingMatrix(MatrixType& rLeftHandSideMatrix, const ElementVariables& rVariables) const; void CalculateAndAddCompressibilityMatrix(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables) const; - void CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, const ElementVariables& rVariables) const; - void CalculateAndAddRHS(VectorType& rRightHandSideVector, ElementVariables& rVariables, unsigned int GPoint); void CalculateAndAddStiffnessForce(VectorType& rRightHandSideVector, @@ -275,42 +263,40 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SmallStrainUPwDiffOrderElement : pub void CalculateAndAddMixBodyForce(VectorType& rRightHandSideVector, ElementVariables& rVariables); - void CalculateAndAddCouplingTerms(VectorType& rRightHandSideVector, ElementVariables& rVariables); + void CalculateAndAddCouplingTerms(VectorType& rRightHandSideVector, ElementVariables& rVariables) const; void CalculateAndAddCompressibilityFlow(VectorType& rRightHandSideVector, const ElementVariables& rVariables) const; + [[nodiscard]] std::vector CalculateRelativePermeabilityValues(const std::vector& rFluidPressures) const; void CalculateAndAddPermeabilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) const; void CalculateAndAddFluidBodyFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables); - double CalculateBulkModulus(const Matrix& ConstitutiveMatrix) const; - double CalculateBiotCoefficient(const ElementVariables& rVariables, const bool& hasBiotCoefficient) const; - Matrix CalculateBMatrix(const Matrix& rDN_DX, const Vector& rN) const; std::vector CalculateBMatrices(const GeometryType::ShapeFunctionsGradientsType& rDN_DXContainer, const Matrix& rNContainer) const; void AssignPressureToIntermediateNodes(); - virtual Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const; - virtual Vector CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements) const; - virtual Vector CalculateStrain(const Matrix& rDeformationGradient, - const Matrix& rB, - const Vector& rDisplacements, - bool UseHenckyStrain) const; - std::vector CalculateStrains(const std::vector& rDeformationGradients, - const std::vector& rBs, - const Vector& rDisplacements, - bool UseHenckyStrain) const; + virtual Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const; Matrix CalculateDeformationGradient(unsigned int GPoint) const; std::vector CalculateDeformationGradients() const; - double CalculateFluidPressure(const ElementVariables& rVariables) const; - - void SetRetentionParameters(const ElementVariables& rVariables, - RetentionLaw::Parameters& rRetentionParameters) const; + /// + /// \brief This function calculates the constitutive matrices, stresses and strains depending on the + /// constitutive parameters. Note that depending on the settings in the rConstitutiveParameters + /// the function could calculate the stress, the constitutive matrix, the strains, or a combination. + /// In our elements we generally always calculate the constitutive matrix and sometimes the stress. + /// + void CalculateAnyOfMaterialResponse(const std::vector& rDeformationGradients, + ConstitutiveLaw::Parameters& rConstitutiveParameters, + const Matrix& rNuContainer, + const GeometryType::ShapeFunctionsGradientsType& rDNu_DXContainer, + std::vector& rStrainVectors, + std::vector& rStressVectors, + std::vector& rConstitutiveMatrices); void CalculateRetentionResponse(ElementVariables& rVariables, RetentionLaw::Parameters& rRetentionParameters, diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.cpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.cpp index f406c08bc01e..13b4c251ab35 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.cpp @@ -12,6 +12,7 @@ // Application includes #include "custom_elements/steady_state_Pw_element.hpp" +#include "custom_utilities/transport_equation_utilities.hpp" namespace Kratos { @@ -152,12 +153,13 @@ void SteadyStatePwElement::CalculateAll(MatrixType& rLef ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); + const auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); - + // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; GPoint++) { // Compute GradNpT, B and StrainVector @@ -168,7 +170,8 @@ void SteadyStatePwElement::CalculateAll(MatrixType& rLef GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; Variables.IntegrationCoefficient = integration_coefficients[GPoint]; @@ -188,11 +191,10 @@ template void SteadyStatePwElement::CalculateAndAddLHS(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables) { - KRATOS_TRY; - - this->CalculateAndAddPermeabilityMatrix(rLeftHandSideMatrix, rVariables); - - KRATOS_CATCH(""); + const auto permeability_matrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( + rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, + rVariables.RelativePermeability, rVariables.IntegrationCoefficient); + rLeftHandSideMatrix += permeability_matrix; } //---------------------------------------------------------------------------------------- diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.hpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.hpp index 4bdfab8a5172..d05eaa60b071 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_element.hpp @@ -45,7 +45,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SteadyStatePwElement : public Transi /// The definition of the sizetype using SizeType = std::size_t; - using BaseType::CalculateRetentionResponse; using BaseType::mConstitutiveLawVector; using BaseType::mIsInitialised; using BaseType::mRetentionLawVector; diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.cpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.cpp index 90d0e179e1fb..69e0201b16a9 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.cpp @@ -149,8 +149,7 @@ void SteadyStatePwInterfaceElement::CalculateAll(MatrixType& rL array_1d RelDispVector; SFGradAuxVariables SFGradAuxVars; - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, detJContainer); @@ -171,7 +170,7 @@ void SteadyStatePwInterfaceElement::CalculateAll(MatrixType& rL InterfaceElementUtilities::FillPermeabilityMatrix( Variables.LocalPermeabilityMatrix, Variables.JointWidth, Prop[TRANSVERSAL_PERMEABILITY]); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.hpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.hpp index 03493024894c..c4f2d73490b5 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_interface_element.hpp @@ -47,7 +47,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SteadyStatePwInterfaceElement /// The definition of the sizetype using SizeType = std::size_t; - using BaseType::CalculateRetentionResponse; using BaseType::mRetentionLawVector; using BaseType::mThisIntegrationMethod; diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.cpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.cpp index bf382761cf4f..196ede25f9c2 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.cpp @@ -211,8 +211,7 @@ void SteadyStatePwPipingElement::CalculateAll(MatrixType& rLeft array_1d RelDispVector; SFGradAuxVariables SFGradAuxVars; - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, detJContainer); @@ -233,7 +232,7 @@ void SteadyStatePwPipingElement::CalculateAll(MatrixType& rLeft InterfaceElementUtilities::FillPermeabilityMatrix( Variables.LocalPermeabilityMatrix, Variables.JointWidth, Prop[TRANSVERSAL_PERMEABILITY]); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; diff --git a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.hpp b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.hpp index 5248f3fd1caa..79ae0d90f880 100644 --- a/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/steady_state_Pw_piping_element.hpp @@ -47,7 +47,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) SteadyStatePwPipingElement /// The definition of the sizetype using SizeType = std::size_t; - using BaseType::CalculateRetentionResponse; using BaseType::mRetentionLawVector; using BaseType::mThisIntegrationMethod; diff --git a/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.cpp b/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.cpp new file mode 100644 index 000000000000..6fe34c99a828 --- /dev/null +++ b/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.cpp @@ -0,0 +1,30 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Richard Faasse +// Marjan Fathian +// +#pragma once + +#include "stress_state_policy.h" + +namespace Kratos +{ + +Vector StressStatePolicy::DefineVoigtVector(std::size_t Dimension) +{ + Vector VoigtVector = ZeroVector(GetVoigtSize(Dimension)); + std::fill_n(VoigtVector.begin(), GetStressTensorSize(Dimension), 1.0); + return VoigtVector; +} + +const Vector StressStatePolicy::VoigtVector2D = StressStatePolicy::DefineVoigtVector(2); +const Vector StressStatePolicy::VoigtVector3D = StressStatePolicy::DefineVoigtVector(3); + +} // namespace Kratos \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.h b/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.h index 273eea886345..f2858be04226 100644 --- a/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.h +++ b/applications/GeoMechanicsApplication/custom_elements/stress_state_policy.h @@ -32,7 +32,35 @@ class StressStatePolicy double DetJ, const Geometry& rGeometry) const = 0; [[nodiscard]] virtual Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const = 0; - [[nodiscard]] virtual std::unique_ptr Clone() const = 0; + [[nodiscard]] virtual std::unique_ptr Clone() const = 0; + [[nodiscard]] virtual const Vector& GetVoigtVector() const = 0; + [[nodiscard]] virtual SizeType GetVoigtSize() const = 0; + [[nodiscard]] virtual SizeType GetStressTensorSize() const = 0; + +protected: + static const Vector VoigtVector2D; + static const Vector VoigtVector3D; + + static constexpr SizeType GetVoigtSize2D() { return VOIGT_SIZE_2D_PLANE_STRAIN; } + + static constexpr SizeType GetVoigtSize3D() { return VOIGT_SIZE_3D; } + + static constexpr SizeType GetStressTensorSize2D() { return STRESS_TENSOR_SIZE_2D; } + + static constexpr SizeType GetStressTensorSize3D() { return STRESS_TENSOR_SIZE_3D; } + +private: + static Vector DefineVoigtVector(std::size_t Dimension); + + static constexpr std::size_t GetVoigtSize(std::size_t Dimension) + { + return Dimension == N_DIM_3D ? GetVoigtSize3D() : GetVoigtSize2D(); + } + + static constexpr std::size_t GetStressTensorSize(std::size_t Dimension) + { + return Dimension == N_DIM_3D ? GetStressTensorSize3D() : GetStressTensorSize2D(); + } }; } // namespace Kratos \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.cpp b/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.cpp index d5204ca379cd..b4f19e2716e4 100644 --- a/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.cpp @@ -58,4 +58,13 @@ std::unique_ptr ThreeDimensionalStressState::Clone() const return std::make_unique(); } +const Vector& ThreeDimensionalStressState::GetVoigtVector() const { return VoigtVector3D; } + +SizeType ThreeDimensionalStressState::GetVoigtSize() const { return GetVoigtSize3D(); } + +SizeType ThreeDimensionalStressState::GetStressTensorSize() const +{ + return GetStressTensorSize3D(); +} + } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.h b/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.h index d8cf8907ebc5..2ef59cce3a20 100644 --- a/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.h +++ b/applications/GeoMechanicsApplication/custom_elements/three_dimensional_stress_state.h @@ -27,6 +27,9 @@ class ThreeDimensionalStressState : public StressStatePolicy const Geometry& rGeometry) const override; [[nodiscard]] Vector CalculateGreenLagrangeStrain(const Matrix& rDeformationGradient) const override; [[nodiscard]] std::unique_ptr Clone() const override; + [[nodiscard]] const Vector& GetVoigtVector() const override; + [[nodiscard]] SizeType GetVoigtSize() const override; + [[nodiscard]] SizeType GetStressTensorSize() const override; }; } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.cpp b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.cpp index 1a009644c290..e35855be6d4d 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.cpp @@ -283,7 +283,7 @@ int TransientPwElement::Check(const ProcessInfo& rCurrentProces template void TransientPwElement::InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) { - KRATOS_TRY; + KRATOS_TRY if (!mIsInitialised) this->Initialize(rCurrentProcessInfo); @@ -291,8 +291,7 @@ void TransientPwElement::InitializeSolutionStep(const ProcessIn const GeometryType& Geom = this->GetGeometry(); const unsigned int NumGPoints = Geom.IntegrationPointsNumber(this->GetIntegrationMethod()); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -303,30 +302,22 @@ void TransientPwElement::InitializeSolutionStep(const ProcessIn // reset hydraulic discharge this->ResetHydraulicDischarge(); - KRATOS_CATCH(""); + KRATOS_CATCH("") } //---------------------------------------------------------------------------------------------------- template -void TransientPwElement::InitializeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) +void TransientPwElement::InitializeNonLinearIteration(const ProcessInfo&) { - KRATOS_TRY; - // nothing - - KRATOS_CATCH(""); } //---------------------------------------------------------------------------------------------------- template -void TransientPwElement::FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) +void TransientPwElement::FinalizeNonLinearIteration(const ProcessInfo&) { - KRATOS_TRY; - // nothing - - KRATOS_CATCH(""); } //---------------------------------------------------------------------------------------------------- @@ -341,8 +332,7 @@ void TransientPwElement::FinalizeSolutionStep(const ProcessInfo const GeometryType& Geom = this->GetGeometry(); const unsigned int NumGPoints = Geom.IntegrationPointsNumber(this->GetIntegrationMethod()); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -450,13 +440,13 @@ void TransientPwElement::CalculateAll(MatrixType& rLeftH ElementVariables Variables; this->InitializeElementVariables(Variables, rCurrentProcessInfo); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); - - const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); + const auto relative_permeability_values = this->CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NContainer, Variables.PressureVector)); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJContainer); + std::vector biot_coefficients(NumGPoints, Prop[BIOT_COEFFICIENT]); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -468,9 +458,13 @@ void TransientPwElement::CalculateAll(MatrixType& rLeftH GeoElementUtilities::InterpolateVariableWithComponents( Variables.BodyAcceleration, Variables.NContainer, Variables.VolumeAcceleration, GPoint); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; @@ -522,7 +516,6 @@ void TransientPwElement::InitializeElementVariables(ElementVari rVariables.DN_DXContainer, rVariables.detJContainer, this->GetIntegrationMethod()); // Retention law - rVariables.FluidPressure = 0.0; rVariables.DegreeOfSaturation = 1.0; rVariables.DerivativeOfSaturation = 0.0; rVariables.RelativePermeability = 1.0; @@ -536,12 +529,16 @@ template void TransientPwElement::CalculateAndAddLHS(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables) { - KRATOS_TRY; + KRATOS_TRY this->CalculateAndAddCompressibilityMatrix(rLeftHandSideMatrix, rVariables); - this->CalculateAndAddPermeabilityMatrix(rLeftHandSideMatrix, rVariables); - KRATOS_CATCH(""); + const auto permeability_matrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( + rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, + rVariables.RelativePermeability, rVariables.IntegrationCoefficient); + rLeftHandSideMatrix += permeability_matrix; + + KRATOS_CATCH("") } //---------------------------------------------------------------------------------------- @@ -560,23 +557,6 @@ void TransientPwElement::CalculateAndAddCompressibilityMatrix(M KRATOS_CATCH(""); } -//---------------------------------------------------------------------------------------- -template -void TransientPwElement::CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, - const ElementVariables& rVariables) -{ - KRATOS_TRY; - - const auto permeability_matrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( - rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.PermeabilityMatrix, - rVariables.RelativePermeability, rVariables.PermeabilityUpdateFactor, rVariables.IntegrationCoefficient); - - // Distribute permeability block matrix into the elemental matrix - rLeftHandSideMatrix += permeability_matrix; - - KRATOS_CATCH(""); -} - //---------------------------------------------------------------------------------------- template void TransientPwElement::CalculateAndAddRHS(VectorType& rRightHandSideVector, diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.hpp b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.hpp index 0297b0917c98..233a40333cf3 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_element.hpp @@ -45,7 +45,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwElement : public UPwSmall /// The definition of the sizetype using SizeType = std::size_t; - using BaseType::CalculateRetentionResponse; using BaseType::mConstitutiveLawVector; using BaseType::mIsInitialised; using BaseType::mRetentionLawVector; @@ -94,9 +93,9 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwElement : public UPwSmall void InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override; - void InitializeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override; + void InitializeNonLinearIteration(const ProcessInfo&) override; - void FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override; + void FinalizeNonLinearIteration(const ProcessInfo&) override; void FinalizeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override; @@ -168,7 +167,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwElement : public UPwSmall void CalculateAndAddCompressibilityMatrix(MatrixType& rLeftHandSideMatrix, ElementVariables& rVariables) override; void CalculateAndAddPermeabilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) override; void CalculateAndAddFluidBodyFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) override; - void CalculateAndAddPermeabilityMatrix(MatrixType& rLeftHandSideMatrix, const ElementVariables& rVariables) override; void CalculateAndAddCompressibilityFlow(VectorType& rRightHandSideVector, ElementVariables& rVariables) override; unsigned int GetNumberOfDOF() const override; diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.cpp b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.cpp index 2fe776903e24..40aa31582bba 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.cpp @@ -143,12 +143,11 @@ void TransientPwInterfaceElement::CalculateMassMatrix(MatrixTyp } template -void TransientPwInterfaceElement::InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) +void TransientPwInterfaceElement::InitializeSolutionStep(const ProcessInfo&) { KRATOS_TRY - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mRetentionLawVector.size(); ++GPoint) { @@ -160,12 +159,11 @@ void TransientPwInterfaceElement::InitializeSolutionStep(const } template -void TransientPwInterfaceElement::FinalizeSolutionStep(const ProcessInfo& rCurrentProcessInfo) +void TransientPwInterfaceElement::FinalizeSolutionStep(const ProcessInfo&) { KRATOS_TRY - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < mRetentionLawVector.size(); ++GPoint) { @@ -295,8 +293,7 @@ void TransientPwInterfaceElement::CalculateOnLobattoIntegration // VG: Perhaps a new parameter to get join width and not minimum joint width const double& JointWidth = Prop[MINIMUM_JOINT_WIDTH]; - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); // Loop over integration points for (unsigned int GPoint = 0; GPoint < NumGPoints; ++GPoint) { @@ -474,8 +471,7 @@ void TransientPwInterfaceElement::CalculateAll(MatrixType& rLef array_1d RelDispVector; SFGradAuxVariables SFGradAuxVars; - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), CurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); const bool hasBiotCoefficient = Prop.Has(BIOT_COEFFICIENT); @@ -498,7 +494,7 @@ void TransientPwInterfaceElement::CalculateAll(MatrixType& rLef InterfaceElementUtilities::FillPermeabilityMatrix( Variables.LocalPermeabilityMatrix, Variables.JointWidth, Prop[TRANSVERSAL_PERMEABILITY]); - CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + this->CalculateRetentionResponse(Variables, RetentionParameters, GPoint); this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); @@ -599,7 +595,7 @@ void TransientPwInterfaceElement::CalculateAndAddPermeabilityMa rVariables.PPMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix( rVariables.GradNpT, rVariables.DynamicViscosityInverse, rVariables.LocalPermeabilityMatrix, - rVariables.RelativePermeability, rVariables.JointWidth, rVariables.IntegrationCoefficient); + rVariables.RelativePermeability * rVariables.JointWidth, rVariables.IntegrationCoefficient); // Distribute permeability block matrix into the elemental matrix rLeftHandSideMatrix += rVariables.PPMatrix; diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.hpp b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.hpp index cb9060cb4bb7..2c7ca8298229 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_interface_element.hpp @@ -44,7 +44,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwInterfaceElement /// The definition of the sizetype using SizeType = std::size_t; - using BaseType::CalculateRetentionResponse; using BaseType::mRetentionLawVector; using BaseType::mThisIntegrationMethod; @@ -109,8 +108,8 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwInterfaceElement void CalculateMassMatrix(MatrixType& rMassMatrix, const ProcessInfo& rCurrentProcessInfo) override; - void InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override; - void FinalizeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override; + void InitializeSolutionStep(const ProcessInfo&) override; + void FinalizeSolutionStep(const ProcessInfo&) override; void CalculateOnIntegrationPoints(const Variable& rVariable, std::vector& rValues, diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_line_element.h b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_line_element.h index 429a232b6db1..156a67a0d0e3 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_Pw_line_element.h +++ b/applications/GeoMechanicsApplication/custom_elements/transient_Pw_line_element.h @@ -75,10 +75,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem const Matrix& r_N_container = GetGeometry().ShapeFunctionsValues(GetIntegrationMethod()); const auto integration_coefficients = CalculateIntegrationCoefficients(det_J_container); - const auto permeability_matrix = CalculatePermeabilityMatrix(dN_dX_container, integration_coefficients, rCurrentProcessInfo); - const auto compressibility_matrix = CalculateCompressibilityMatrix(r_N_container, integration_coefficients, rCurrentProcessInfo); + const auto permeability_matrix = CalculatePermeabilityMatrix(dN_dX_container, integration_coefficients); + const auto compressibility_matrix = CalculateCompressibilityMatrix(r_N_container, integration_coefficients); - const auto fluid_body_vector = CalculateFluidBodyVector(r_N_container, dN_dX_container, rCurrentProcessInfo, integration_coefficients); + const auto fluid_body_vector = CalculateFluidBodyVector(r_N_container, dN_dX_container, integration_coefficients); AddContributionsToLhsMatrix(rLeftHandSideMatrix, permeability_matrix, compressibility_matrix, rCurrentProcessInfo[DT_PRESSURE_COEFFICIENT]); AddContributionsToRhsVector(rRightHandSideVector, permeability_matrix, compressibility_matrix, fluid_body_vector); @@ -220,10 +220,9 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem BoundedMatrix CalculatePermeabilityMatrix( const GeometryType::ShapeFunctionsGradientsType& rShapeFunctionGradients, - const Vector& rIntegrationCoefficients, - const ProcessInfo& rCurrentProcessInfo) const + const Vector& rIntegrationCoefficients) const { - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); BoundedMatrix constitutive_matrix; const auto& r_properties = GetProperties(); GeoElementUtilities::FillPermeabilityMatrix(constitutive_matrix, r_properties); @@ -236,18 +235,16 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem double dynamic_viscosity_inverse = 1.0 / r_properties[DYNAMIC_VISCOSITY]; result += GeoTransportEquationUtilities::CalculatePermeabilityMatrix( rShapeFunctionGradients[integration_point_index], dynamic_viscosity_inverse, constitutive_matrix, - RelativePermeability, 1.0, rIntegrationCoefficients[integration_point_index]); + RelativePermeability, rIntegrationCoefficients[integration_point_index]); } return result; } - BoundedMatrix CalculateCompressibilityMatrix( - const Matrix& rNContainer, - const Vector& rIntegrationCoefficients, - const ProcessInfo& rCurrentProcessInfo) const + BoundedMatrix CalculateCompressibilityMatrix(const Matrix& rNContainer, + const Vector& rIntegrationCoefficients) const { const auto& r_properties = GetProperties(); - RetentionLaw::Parameters parameters(r_properties, rCurrentProcessInfo); + RetentionLaw::Parameters parameters(r_properties); auto retention_law = RetentionLawFactory::Clone(r_properties); auto result = BoundedMatrix{ZeroMatrix{TNumNodes, TNumNodes}}; @@ -255,7 +252,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem integration_point_index < GetGeometry().IntegrationPointsNumber(GetIntegrationMethod()); ++integration_point_index) { const auto N = Vector{row(rNContainer, integration_point_index)}; - const double BiotModulusInverse = CalculateBiotModulusInverse(rCurrentProcessInfo, integration_point_index); + const double BiotModulusInverse = CalculateBiotModulusInverse(integration_point_index); result += GeoTransportEquationUtilities::CalculateCompressibilityMatrix( N, BiotModulusInverse, rIntegrationCoefficients[integration_point_index]); } @@ -287,8 +284,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem } - double CalculateBiotModulusInverse(const ProcessInfo& rCurrentProcessInfo, - const unsigned int integrationPointIndex) const + double CalculateBiotModulusInverse(const unsigned int integrationPointIndex) const { const auto& r_properties = GetProperties(); const double biot_coefficient = r_properties[BIOT_COEFFICIENT]; @@ -300,7 +296,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem double result = (biot_coefficient - r_properties[POROSITY]) / r_properties[BULK_MODULUS_SOLID] + r_properties[POROSITY] / bulk_fluid; - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); const double degree_of_saturation = mRetentionLawVector[integrationPointIndex]->CalculateSaturation(RetentionParameters); const double derivative_of_saturation = mRetentionLawVector[integrationPointIndex]->CalculateDerivativeOfSaturation(RetentionParameters); @@ -310,18 +306,18 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem } - void InitializeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override + void InitializeSolutionStep(const ProcessInfo&) override { - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); for (auto retention_law : mRetentionLawVector) { retention_law->InitializeSolutionStep(RetentionParameters); } } - void FinalizeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override + void FinalizeSolutionStep(const ProcessInfo&) override { - RetentionLaw::Parameters RetentionParameters(this->GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(this->GetProperties()); for (auto retention_law : mRetentionLawVector) { retention_law->FinalizeSolutionStep(RetentionParameters); } @@ -331,7 +327,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem array_1d CalculateFluidBodyVector( const Matrix& rNContainer, const GeometryType::ShapeFunctionsGradientsType& rShapeFunctionGradients, - const ProcessInfo& rCurrentProcessInfo, const Vector& rIntegrationCoefficients) const { const std::size_t number_integration_points = GetGeometry().IntegrationPointsNumber(GetIntegrationMethod()); @@ -346,7 +341,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientPwLineElement : public Elem BoundedMatrix constitutive_matrix; GeoElementUtilities::FillPermeabilityMatrix(constitutive_matrix, r_properties); - RetentionLaw::Parameters RetentionParameters(GetProperties(), rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(GetProperties()); array_1d volume_acceleration; GeoElementUtilities::GetNodalVariableVector(volume_acceleration, GetGeometry(), VOLUME_ACCELERATION); diff --git a/applications/GeoMechanicsApplication/custom_elements/transient_thermal_element.h b/applications/GeoMechanicsApplication/custom_elements/transient_thermal_element.h index 011351d2eed9..451dec406238 100644 --- a/applications/GeoMechanicsApplication/custom_elements/transient_thermal_element.h +++ b/applications/GeoMechanicsApplication/custom_elements/transient_thermal_element.h @@ -15,6 +15,7 @@ #pragma once #include "custom_constitutive/thermal_dispersion_law.h" +#include "custom_constitutive/thermal_filter_law.h" #include "custom_retention/retention_law_factory.h" #include "custom_utilities/dof_utilities.h" #include "geo_mechanics_application_variables.h" @@ -87,8 +88,8 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientThermalElement : public Ele const auto integration_coefficients = CalculateIntegrationCoefficients(det_J_container); const auto conductivity_matrix = - CalculateConductivityMatrix(dN_dX_container, integration_coefficients, rCurrentProcessInfo); - const auto capacity_matrix = CalculateCapacityMatrix(integration_coefficients, rCurrentProcessInfo); + CalculateConductivityMatrix(dN_dX_container, integration_coefficients); + const auto capacity_matrix = CalculateCapacityMatrix(integration_coefficients); AddContributionsToLhsMatrix(rLeftHandSideMatrix, conductivity_matrix, capacity_matrix, rCurrentProcessInfo[DT_TEMPERATURE_COEFFICIENT]); @@ -265,13 +266,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientThermalElement : public Ele BoundedMatrix CalculateConductivityMatrix( const GeometryType::ShapeFunctionsGradientsType& rShapeFunctionGradients, - const Vector& rIntegrationCoefficients, - const ProcessInfo& rCurrentProcessInfo) const + const Vector& rIntegrationCoefficients) const { - const std::size_t number_of_dimensions = GetGeometry().LocalSpaceDimension(); - - GeoThermalDispersionLaw law{number_of_dimensions}; - const auto constitutive_matrix = law.CalculateThermalDispersionMatrix(GetProperties(), rCurrentProcessInfo); + const auto law = CreateThermalLaw(); + const auto constitutive_matrix = law->CalculateThermalDispersionMatrix(GetProperties()); auto result = BoundedMatrix{ZeroMatrix{TNumNodes, TNumNodes}}; for (unsigned int integration_point_index = 0; @@ -286,11 +284,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientThermalElement : public Ele return result; } - BoundedMatrix CalculateCapacityMatrix(const Vector& rIntegrationCoefficients, - const ProcessInfo& rCurrentProcessInfo) const + BoundedMatrix CalculateCapacityMatrix(const Vector& rIntegrationCoefficients) const { const auto& r_properties = GetProperties(); - RetentionLaw::Parameters parameters(r_properties, rCurrentProcessInfo); + RetentionLaw::Parameters parameters(r_properties); auto retention_law = RetentionLawFactory::Clone(r_properties); const double saturation = retention_law->CalculateSaturation(parameters); const auto c_water = r_properties[POROSITY] * saturation * r_properties[DENSITY_WATER] * @@ -320,6 +317,29 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) TransientThermalElement : public Ele return result; } + std::unique_ptr CreateThermalLaw() const + { + const std::size_t number_of_dimensions = GetGeometry().LocalSpaceDimension(); + std::unique_ptr law; + + if (GetProperties().Has(THERMAL_LAW_NAME)) { + const std::string& rThermalLawName = GetProperties()[THERMAL_LAW_NAME]; + if (rThermalLawName == "GeoThermalDispersionLaw") { + law = std::make_unique(number_of_dimensions); + } + else if (rThermalLawName == "GeoThermalFilterLaw") { + law = std::make_unique(); + } + else { + KRATOS_ERROR << "Undefined THERMAL_LAW_NAME! " << rThermalLawName << std::endl; + } + } + else { + law = std::make_unique(number_of_dimensions); + } + return law; + } + [[nodiscard]] DofsVectorType GetDofs() const { return Geo::DofUtilities::ExtractDofsFromNodes(GetGeometry(), TEMPERATURE); diff --git a/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.cpp b/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.cpp index 8572b942b86a..fc7324687682 100644 --- a/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.cpp +++ b/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.cpp @@ -15,6 +15,7 @@ // Project includes #include "custom_elements/updated_lagrangian_U_Pw_diff_order_element.hpp" #include "custom_utilities/math_utilities.h" +#include "custom_utilities/transport_equation_utilities.hpp" #include "utilities/math_utils.h" namespace Kratos @@ -63,45 +64,43 @@ void UpdatedLagrangianUPwDiffOrderElement::CalculateAll(MatrixType& rLeft if (CalculateResidualVectorFlag) ConstitutiveParameters.GetOptions().Set(ConstitutiveLaw::COMPUTE_STRESS); - // create general parameters of retention law - RetentionLaw::Parameters RetentionParameters(rProp, rCurrentProcessInfo); + RetentionLaw::Parameters RetentionParameters(rProp); // Loop over integration points const GeometryType::IntegrationPointsArrayType& IntegrationPoints = rGeom.IntegrationPoints(this->GetIntegrationMethod()); - const bool hasBiotCoefficient = rProp.Has(BIOT_COEFFICIENT); const auto b_matrices = this->CalculateBMatrices(Variables.DNu_DXContainer, Variables.NuContainer); const auto deformation_gradients = this->CalculateDeformationGradients(); - const auto determinants_of_deformation_gradients = - GeoMechanicsMathUtilities::CalculateDeterminants(deformation_gradients); const auto integration_coefficients = this->CalculateIntegrationCoefficients(IntegrationPoints, Variables.detJuContainer); - const auto strain_vectors = this->CalculateStrains( - deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain); + auto strain_vectors = StressStrainUtilities::CalculateStrains( + deformation_gradients, b_matrices, Variables.DisplacementVector, Variables.UseHenckyStrain, + this->GetStressStatePolicy().GetVoigtSize()); + std::vector constitutive_matrices; + this->CalculateAnyOfMaterialResponse(deformation_gradients, ConstitutiveParameters, + Variables.NuContainer, Variables.DNu_DXContainer, + strain_vectors, mStressVector, constitutive_matrices); + const auto biot_coefficients = GeoTransportEquationUtilities::CalculateBiotCoefficients( + constitutive_matrices, this->GetProperties()); + const auto relative_permeability_values = CalculateRelativePermeabilityValues( + GeoTransportEquationUtilities::CalculateFluidPressures(Variables.NpContainer, Variables.PressureVector)); - // Computing in all integrations points for (IndexType GPoint = 0; GPoint < IntegrationPoints.size(); ++GPoint) { - // Compute element kinematics B, F, DNu_DX ... this->CalculateKinematics(Variables, GPoint); Variables.B = b_matrices[GPoint]; - // Compute strain - Variables.F = deformation_gradients[GPoint]; - Variables.detF = determinants_of_deformation_gradients[GPoint]; - Variables.StrainVector = strain_vectors[GPoint]; - - // set gauss points variables to constitutivelaw parameters - this->SetConstitutiveParameters(Variables, ConstitutiveParameters); - - // Compute constitutive tensor and stresses - ConstitutiveParameters.SetStressVector(mStressVector[GPoint]); - mConstitutiveLawVector[GPoint]->CalculateMaterialResponseCauchy(ConstitutiveParameters); + Variables.F = deformation_gradients[GPoint]; + Variables.StrainVector = strain_vectors[GPoint]; + Variables.ConstitutiveMatrix = constitutive_matrices[GPoint]; CalculateRetentionResponse(Variables, RetentionParameters, GPoint); + Variables.RelativePermeability = relative_permeability_values[GPoint]; - // calculate Bulk modulus from stiffness matrix - this->InitializeBiotCoefficients(Variables, hasBiotCoefficient); + Variables.BiotCoefficient = biot_coefficients[GPoint]; + Variables.BiotModulusInverse = GeoTransportEquationUtilities::CalculateBiotModulusInverse( + Variables.BiotCoefficient, Variables.DegreeOfSaturation, + Variables.DerivativeOfSaturation, this->GetProperties()); Variables.IntegrationCoefficient = integration_coefficients[GPoint]; diff --git a/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.hpp b/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.hpp index 6c992886e133..1fbdec4e411f 100644 --- a/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.hpp +++ b/applications/GeoMechanicsApplication/custom_elements/updated_lagrangian_U_Pw_diff_order_element.hpp @@ -67,7 +67,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) UpdatedLagrangianUPwDiffOrderElement /// The definition of the sizetype using SizeType = std::size_t; - using SmallStrainUPwDiffOrderElement::CalculateCauchyStrain; using SmallStrainUPwDiffOrderElement::CalculateDerivativesOnInitialConfiguration; using SmallStrainUPwDiffOrderElement::CalculateGreenLagrangeStrain; using SmallStrainUPwDiffOrderElement::mConstitutiveLawVector; diff --git a/applications/GeoMechanicsApplication/custom_retention/retention_law.h b/applications/GeoMechanicsApplication/custom_retention/retention_law.h index 8cad6da9cb43..e4e87b992a16 100644 --- a/applications/GeoMechanicsApplication/custom_retention/retention_law.h +++ b/applications/GeoMechanicsApplication/custom_retention/retention_law.h @@ -24,27 +24,30 @@ #include "includes/serializer.h" #include -namespace Kratos { +namespace Kratos +{ /** * Base class of retention laws. */ -class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { +class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw +{ public: /** * Type definitions * NOTE: geometries are assumed to be of type Node for all problems */ using ProcessInfoType = ProcessInfo; - using SizeType = std::size_t; - using GeometryType = Geometry; + using SizeType = std::size_t; + using GeometryType = Geometry; /** * Counted pointer of RetentionLaw */ KRATOS_CLASS_POINTER_DEFINITION(RetentionLaw); - class Parameters { + class Parameters + { KRATOS_CLASS_POINTER_DEFINITION(Parameters); /** @@ -64,17 +67,14 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { */ public: - Parameters(const Properties& rMaterialProperties, - const ProcessInfo& rCurrentProcessInfo) - : mrCurrentProcessInfo(rCurrentProcessInfo), - mrMaterialProperties(rMaterialProperties){}; + explicit Parameters(const Properties& rMaterialProperties) + : mrMaterialProperties(rMaterialProperties) + { + } ~Parameters() = default; - void SetFluidPressure(double FluidPressure) - { - mFluidPressure = FluidPressure; - }; + void SetFluidPressure(double FluidPressure) { mFluidPressure = FluidPressure; }; double GetFluidPressure() const { @@ -84,20 +84,11 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { return mFluidPressure.value(); } - const ProcessInfo& GetProcessInfo() const - { - return mrCurrentProcessInfo; - } - - const Properties& GetMaterialProperties() const - { - return mrMaterialProperties; - } + const Properties& GetMaterialProperties() const { return mrMaterialProperties; } private: std::optional mFluidPressure; - const ProcessInfo& mrCurrentProcessInfo; - const Properties& mrMaterialProperties; + const Properties& mrMaterialProperties; }; // class Parameters end @@ -121,9 +112,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { * @param rValue a reference to the returned value * @param rValue output: the value of the specified variable */ - virtual double& CalculateValue(Parameters& rParameters, - const Variable& rThisVariable, - double& rValue) = 0; + virtual double& CalculateValue(Parameters& rParameters, const Variable& rThisVariable, double& rValue) = 0; virtual double CalculateSaturation(Parameters& rParameters) = 0; @@ -143,9 +132,9 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { * @param rElementGeometry the geometry of the current element * @param rCurrentProcessInfo process info */ - virtual void InitializeMaterial(const Properties& rMaterialProperties, + virtual void InitializeMaterial(const Properties& rMaterialProperties, const GeometryType& rElementGeometry, - const Vector& rShapeFunctionsValues); + const Vector& rShapeFunctionsValues); virtual void Initialize(Parameters& rParameters); @@ -175,9 +164,9 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { * @param rShapeFunctionsValues the shape functions values in the current integration point * @param the current ProcessInfo instance */ - virtual void ResetMaterial(const Properties& rMaterialProperties, + virtual void ResetMaterial(const Properties& rMaterialProperties, const GeometryType& rElementGeometry, - const Vector& rShapeFunctionsValues); + const Vector& rShapeFunctionsValues); /** * This function is designed to be called once to perform all the checks @@ -188,8 +177,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { * @param rCurrentProcessInfo * @return */ - virtual int Check(const Properties& rMaterialProperties, - const ProcessInfo& rCurrentProcessInfo) = 0; + virtual int Check(const Properties& rMaterialProperties, const ProcessInfo& rCurrentProcessInfo) = 0; /** * @brief This method is used to check that two Retention Laws are the same type (references) @@ -212,22 +200,13 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) RetentionLaw { } /// Turn back information as a string. - virtual std::string Info() const - { - return "RetentionLaw"; - } + virtual std::string Info() const { return "RetentionLaw"; } /// Print information about this object. - virtual void PrintInfo(std::ostream& rOStream) const - { - rOStream << Info(); - } + virtual void PrintInfo(std::ostream& rOStream) const { rOStream << Info(); } /// Print object's data. - virtual void PrintData(std::ostream& rOStream) const - { - rOStream << "RetentionLaw has no data"; - } + virtual void PrintData(std::ostream& rOStream) const { rOStream << "RetentionLaw has no data"; } private: friend class Serializer; diff --git a/applications/GeoMechanicsApplication/custom_utilities/README.md b/applications/GeoMechanicsApplication/custom_utilities/README.md index ef3ce4d2fc81..f74b962e8e03 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/README.md +++ b/applications/GeoMechanicsApplication/custom_utilities/README.md @@ -58,6 +58,14 @@ $$M = \int_\Omega N_{u}^T \rho N_u d\Omega$$ Where $\Omega$ is the domain, $N_u$ is the displacement shape function and $\rho$ is the density matrix that holds density for all directions. +### Stiffness Matrix (K) + +The mathematical definition is: +$$K = \int_\Omega B^T C_{constitutive} B d\Omega$$ + +Where $\Omega$ is the domain, $B$ is the B-matrix and $C_{constitutive}$ is the constitutive matrix. + + ### Damping Matrix (D) The mathematical definition is: @@ -65,8 +73,10 @@ $$D = \alpha_R M + \beta_R K$$ Where $M$ and $K$ are the mass and stiffness matrices respectively and $\alpha_R$ and $\beta_R$ are the coefficients from the Rayleigh Method. -File equation_of_motion_utilities.hpp includes +File equation_of_motion_utilities.h includes - CalculateMassMatrix function +- CalculateStiffnessMatrixGPoint provides a stiffness matrix for a specific integration point +- CalculateStiffnessMatrix provides a stiffness matrix for an element - CalculateDampingMatrix function - CalculateIntegrationCoefficientsInitialConfiguration function that calculates integration coefficient for all integration points diff --git a/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.cpp b/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.cpp index 63def1f5e8c0..03723294d843 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.cpp +++ b/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.cpp @@ -26,4 +26,19 @@ int ConstitutiveLawUtilities::GetStateVariableIndex(const Variable& rThi return index - 1; } +void ConstitutiveLawUtilities::SetConstitutiveParameters(ConstitutiveLaw::Parameters& rConstitutiveParameters, + Vector& rStrainVector, + Matrix& rConstitutiveMatrix, + const Vector& rN, + const Matrix& rGradNpT, + const Matrix& rF, + double detF) +{ + rConstitutiveParameters.SetStrainVector(rStrainVector); + rConstitutiveParameters.SetConstitutiveMatrix(rConstitutiveMatrix); + rConstitutiveParameters.SetShapeFunctionsValues(rN); + rConstitutiveParameters.SetShapeFunctionsDerivatives(rGradNpT); + rConstitutiveParameters.SetDeformationGradientF(rF); + rConstitutiveParameters.SetDeterminantF(detF); +} } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.hpp b/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.hpp index 0b24e0ecd4ca..3a3947e048fd 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.hpp +++ b/applications/GeoMechanicsApplication/custom_utilities/constitutive_law_utilities.hpp @@ -15,6 +15,7 @@ // Project includes #include "containers/variable.h" +#include "includes/constitutive_law.h" namespace Kratos { @@ -24,6 +25,14 @@ class ConstitutiveLawUtilities public: static int GetStateVariableIndex(const Variable& rThisVariable); + static void SetConstitutiveParameters(ConstitutiveLaw::Parameters& rConstitutiveParameters, + Vector& rStrainVector, + Matrix& rConstitutiveMatrix, + const Vector& rN, + const Matrix& rGradNpT, + const Matrix& rF, + double detF); + }; /* Class ConstitutiveLawUtilities*/ } // namespace Kratos \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.cpp b/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.cpp index b46c7f6194cc..7e2c1abc722d 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.cpp +++ b/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.cpp @@ -66,4 +66,23 @@ Matrix GeoEquationOfMotionUtilities::CalculateDampingMatrix(double Raylei return RayleighAlpha * rMassMatrix + RayleighBeta * rStiffnessMatrix; } +Matrix GeoEquationOfMotionUtilities::CalculateStiffnessMatrixGPoint(const Matrix& rB, + const Matrix& rConstitutiveMatrix, + double IntegrationCoefficient) +{ + return prod(trans(rB), Matrix(prod(rConstitutiveMatrix, rB))) * IntegrationCoefficient; +} + +Matrix GeoEquationOfMotionUtilities::CalculateStiffnessMatrix(const std::vector& rBs, + const std::vector& rConstitutiveMatrices, + const std::vector& rIntegrationCoefficients) +{ + Matrix result = ZeroMatrix(rBs[0].size2(), rBs[0].size2()); + for (unsigned int GPoint = 0; GPoint < rBs.size(); ++GPoint) { + result += CalculateStiffnessMatrixGPoint(rBs[GPoint], rConstitutiveMatrices[GPoint], + rIntegrationCoefficients[GPoint]); + } + return result; +} + } /* namespace Kratos.*/ diff --git a/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.h b/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.h index 847c78f4687e..2cc8f8a8a995 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.h +++ b/applications/GeoMechanicsApplication/custom_utilities/equation_of_motion_utilities.h @@ -41,5 +41,13 @@ class GeoEquationOfMotionUtilities const Matrix& rMassMatrix, const Matrix& rStiffnessMatrix); + static Matrix CalculateStiffnessMatrixGPoint(const Matrix& rB, + const Matrix& rConstitutiveMatrix, + double IntegrationCoefficient); + + static Matrix CalculateStiffnessMatrix(const std::vector& rBs, + const std::vector& rConstitutiveMatrices, + const std::vector& rIntegrationCoefficients); + }; /* Class GeoTransportEquationUtilities*/ } /* namespace Kratos.*/ diff --git a/applications/GeoMechanicsApplication/custom_utilities/math_utilities.cpp b/applications/GeoMechanicsApplication/custom_utilities/math_utilities.cpp index 6db487777b90..4af8f9033718 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/math_utilities.cpp +++ b/applications/GeoMechanicsApplication/custom_utilities/math_utilities.cpp @@ -10,7 +10,10 @@ // Main authors: Richard Faasse // +#include + #include "math_utilities.h" +#include "utilities/math_utils.h" std::vector Kratos::GeoMechanicsMathUtilities::CalculateDeterminants(const std::vector& rMatrices) { diff --git a/applications/GeoMechanicsApplication/custom_utilities/math_utilities.h b/applications/GeoMechanicsApplication/custom_utilities/math_utilities.h index b72469d6bfe2..395fbbc49b88 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/math_utilities.h +++ b/applications/GeoMechanicsApplication/custom_utilities/math_utilities.h @@ -7,1085 +7,22 @@ // // License: geo_mechanics_application/license.txt // -// Main authors: JMCarbonell, -// Vahid Galavi +// Main authors: Richard Faasse // #pragma once -#ifdef FIND_MAX -#undef FIND_MAX -#endif +#include -#define FIND_MAX(a, b) ((a) > (b) ? (a) : (b)) - -// System includes -#include - -// External includes - -// Project includes -#include "geometries/point.h" -#include "includes/global_variables.h" -#include "utilities/math_utils.h" +#include "includes/kratos_export_api.h" +#include "includes/ublas_interface.h" namespace Kratos { + class KRATOS_API(GEO_MECHANICS_APPLICATION) GeoMechanicsMathUtilities { public: - /** - * @name type definitions - * @{ - */ - using MatrixType = Matrix; - using VectorType = Vector; - using IndexType = unsigned int; - using SizeType = unsigned int; - using FourthOrderTensorType = DenseVector>; - - /** - * @} - */ - /** - * calculates the solutions for a given cubic polynomial equation - * 0= a*x^3+b*x^2+c*x+d - * @param a coefficient - * @param b coefficient - * @param c coefficient - * @param d coefficient - * @param ZeroTol number treated as zero - * @return Vector of solutions - * WARNING only valid cubic (not quadratic, not linear, not constant) equations with - * three real (not complex) solutions - */ - - static inline bool CardanoFormula(double a, double b, double c, double d, Vector& solution) - { - solution.resize(3, false); - noalias(solution) = ZeroVector(3); - - if (a == 0) { - std::cout << "This is not a cubic equation: CardanoFormula" << std::endl; - - return false; - } - - double p = (3.0 * a * c - b * b) / (3.0 * a * a); - - double q = 2.0 * b * b * b / (27.0 * a * a * a) - b * c / (3.0 * a * a) + d / a; - - double discriminante = p * p * p / 27.0 + q * q / 4.0; - - if (discriminante > 0) { - return false; - } - - if (discriminante == 0) { - if (a == 0) return false; - - solution(0) = pow(q / 2.0, 1.0 / 3.0) - b / (3 * a); - solution(1) = pow(q / 2.0, 1.0 / 3.0) - b / (3 * a); - solution(2) = pow(-4.0 * q, 1.0 / 3.0) - b / (3 * a); - - return true; - } - - if (p < 0) - return false; // in this case the square roots below will be negative. This substitutes with better efficiency lines 100-102 - - solution(0) = -sqrt(-4.0 / 3.0 * p) * - cos(1.0 / 3.0 * acos(-q / 2.0 * sqrt(-27.0 / (p * p * p))) + Globals::Pi / 3.0) - - b / (3 * a); - solution(1) = sqrt(-4.0 / 3.0 * p) * cos(1.0 / 3.0 * acos(-q / 2.0 * sqrt(-27.0 / (p * p * p)))) - - b / (3 * a); - solution(2) = -sqrt(-4.0 / 3.0 * p) * - cos(1.0 / 3.0 * acos(-q / 2.0 * sqrt(-27.0 / (p * p * p))) - Globals::Pi / 3.0) - - b / (3 * a); - - return true; - } - - /** - * @} - */ - /** - * calculates Eigenvalues of given square matrix A. - * The QR Algorithm with shifts is used - * @param A the given square matrix the eigenvalues are to be calculated. - * @param tolerance convergence criteria - * @param zero number treated as zero - * @return Vector of eigenvalues - * WARNING only valid for 2*2 and 3*3 Matrices yet - */ - - static inline Vector EigenValues(const Matrix& A, double tolerance, double zero) - { - int dim = A.size1(); - - Matrix Convergence(2, dim); - noalias(Convergence) = ZeroMatrix(2, dim); - - double delta = 0.0; - - double abs = 0.0; - - Vector Result(dim); - noalias(Result) = ZeroVector(dim); - - Matrix HelpA(dim, dim); - noalias(HelpA) = ZeroMatrix(dim, dim); - - Matrix HelpQ(dim, dim); - noalias(HelpQ) = ZeroMatrix(dim, dim); - - Matrix HelpR(dim, dim); - noalias(HelpR) = ZeroMatrix(dim, dim); - - HelpA = A; - - bool is_converged = false; - unsigned int max_iters = 10; - unsigned int iter = 0; - - while (is_converged == false && iter < max_iters) { - double shift = HelpA((dim - 1), (dim - 1)); - // - for (int i = 0; i < dim; i++) { - HelpA(i, i) = HelpA(i, i) - shift; - } - - GeoMechanicsMathUtilities::QRFactorization(HelpA, HelpQ, HelpR); - - HelpA = ZeroMatrix(dim, dim); - - for (int i = 0; i < dim; i++) { - HelpA(i, i) += shift; - for (int j = 0; j < dim; j++) { - for (int k = 0; k < dim; k++) { - HelpA(i, j) += HelpR(i, k) * HelpQ(k, j); - } - } - } - - delta = 0.0; - - abs = 0.0; - - for (int i = 0; i < dim; i++) { - Convergence(0, i) = Convergence(1, i); - Convergence(1, i) = HelpA(i, i); - delta += (Convergence(1, i) - Convergence(0, i)) * (Convergence(1, i) - Convergence(0, i)); - abs += (Convergence(1, i)) * (Convergence(1, i)); - } - - delta = sqrt(delta); - - abs = sqrt(abs); - - if (abs < zero) abs = 1.0; - - if (delta < zero || (delta / abs) < tolerance) is_converged = true; - - iter++; - } - - for (int i = 0; i < dim; i++) { - Result(i) = HelpA(i, i); - - if (fabs(Result(i)) < zero) Result(i) = 0.0; - } - - return Result; - } - - /** - * @} - */ - /** - * calculates the eigenvectiors using a direct method. - * @param A the given square matrix the eigenvalues are to be calculated. - * WARNING only valid symmetric 3*3 Matrices - */ - - static inline Vector EigenValuesDirectMethod(const Matrix& A) - { - // Given a real symmetric 3x3 matrix A, compute the eigenvalues - int dim = A.size1(); - Vector Result(dim); - noalias(Result) = ZeroVector(dim); - - const double p1 = A(0, 1) * A(0, 1) + A(0, 2) * A(0, 2) + A(1, 2) * A(1, 2); - if (p1 == 0) { // A is diagonal. - Result[0] = A(0, 0); - Result[1] = A(1, 1); - Result[2] = A(2, 2); - return Result; - } - - const double q = (A(0, 0) + A(1, 1) + A(2, 2)) / 3.0; - const double p2 = (A(0, 0) - q) * (A(0, 0) - q) + (A(1, 1) - q) * (A(1, 1) - q) + - (A(2, 2) - q) * (A(2, 2) - q) + 2.0 * p1; - const double p = sqrt(p2 / 6.0); - - Matrix B(3, 3); - const double inv_p = 1.0 / p; - - // B = (1 / p) * (A - q * I) where I is the identity matrix - B(0, 0) = inv_p * (A(0, 0) - q); - B(1, 1) = inv_p * (A(1, 1) - q); - B(2, 2) = inv_p * (A(2, 2) - q); - B(0, 1) = inv_p * A(0, 1); - B(1, 0) = inv_p * A(1, 0); - B(0, 2) = inv_p * A(0, 2); - B(2, 0) = inv_p * A(2, 0); - B(1, 2) = inv_p * A(1, 2); - B(2, 1) = inv_p * A(2, 1); - - double r = 0.5 * (B(0, 0) * B(1, 1) * B(2, 2) + B(0, 1) * B(1, 2) * B(2, 0) + - B(1, 0) * B(2, 1) * B(0, 2) - B(2, 0) * B(1, 1) * B(0, 2) - - B(1, 0) * B(0, 1) * B(2, 2) - B(0, 0) * B(2, 1) * B(1, 2)); - - // In exact arithmetic for a symmetric matrix -1 <= r <= 1 - // but computation error can leave it slightly outside this range. - double phi = 0.0; - if (r <= -1) { - phi = Globals::Pi / 3.0; - } else if (r >= 1) { - phi = 0.0; - } else { - phi = acos(r) / 3.0; - } - - // the eigenvalues satisfy eig3 <= eig2 <= eig1 - Result[0] = q + 2.0 * p * cos(phi); - Result[2] = q + 2.0 * p * cos(phi + (2.0 * Globals::Pi / 3.0)); - Result[1] = 3.0 * q - Result[0] - Result[2]; //% since trace(A) = eig1 + eig2 + eig3 - - return Result; - } - - /** - * @} - */ - /** - * calculates the QR Factorization of given square matrix A=QR. - * The Factorization is performed using the householder algorithm - * @param A the given square matrix the factorization is to be calculated. - * @param Q the result matrix Q - * @param R the result matrix R - */ - - static inline void QRFactorization(const MatrixType& A, MatrixType& Q, MatrixType& R) - { - // QR Factorization with Householder-Algo - int dim = A.size1(); - - Vector y(dim); - - Vector w(dim); - - R.resize(dim, dim, false); - - noalias(R) = ZeroMatrix(dim, dim); - - Q.resize(dim, dim, false); - - noalias(Q) = ZeroMatrix(dim, dim); - - Matrix Help(A.size1(), A.size2()); - noalias(Help) = A; - - Matrix unity(dim, dim); - noalias(unity) = ZeroMatrix(dim, dim); - - for (int j = 0; j < dim; j++) - unity(j, j) = 1.0; - - std::vector HelpQ(dim - 1); - - std::vector HelpR(dim - 1); - - for (int i = 0; i < dim - 1; i++) { - HelpQ[i].resize(dim, dim, false); - HelpR[i].resize(dim, dim, false); - noalias(HelpQ[i]) = unity; - noalias(HelpR[i]) = ZeroMatrix(dim, dim); - } - - for (int iteration = 0; iteration < dim - 1; iteration++) { - // Vector y - for (int i = iteration; i < dim; i++) - y(i) = Help(i, iteration); - - // Helpvalue l - double normy = 0.0; - - for (int i = iteration; i < dim; i++) - normy += y(i) * y(i); - - normy = sqrt(normy); - - double l = sqrt((normy * (normy + fabs(y(iteration)))) / 2); - - double k = 0.0; - - if (y[iteration] != 0) k = -y(iteration) / fabs(y(iteration)) * normy; - else k = -normy; - - for (int i = iteration; i < dim; i++) { - double e = 0; - - if (i == iteration) e = 1; - - w(i) = 1 / (2 * l) * (y(i) - k * e); - } - - for (int i = iteration; i < dim; i++) - for (int j = iteration; j < dim; j++) - HelpQ[iteration](i, j) = unity(i, j) - 2 * w(i) * w(j); - - for (int i = iteration; i < dim; i++) - for (int j = iteration; j < dim; j++) - for (int k = iteration; k < dim; k++) - HelpR[iteration](i, j) += HelpQ[iteration](i, k) * Help(k, j); - - Help = HelpR[iteration]; - } - - // Assembling R - for (int k = 0; k < dim - 1; k++) { - for (int i = k; i < dim; i++) - for (int j = k; j < dim; j++) - R(i, j) = HelpR[k](i, j); - } - - for (int k = 1; k < dim - 1; k++) { - for (int i = 0; i < dim; i++) - for (int j = 0; j < dim; j++) - for (int l = 0; l < dim; l++) - Q(i, j) += HelpQ[(k - 1)](i, l) * HelpQ[k](l, j); - noalias(HelpQ[k]) = Q; - } - if (dim - 1 == 1) noalias(Q) = HelpQ[0]; - } - - /** - * @} - */ - /** - * calculates the eigenvectors and eigenvalues of given symmetric matrix A. - * The eigenvectors and eigenvalues are calculated using the iterative - * Gauss-Seidel-method - * @param A the given symmetric matrix where the eigenvectors have to be calculated. - * @param vectors where the eigenvectors will be stored - * @param lambda wher the eigenvalues will be stored - * @param zero_tolerance the largest value considered to be zero - * @param max_iterations allowed - */ - - static inline void EigenVectors(const MatrixType& A, - MatrixType& vectors, - VectorType& lambda, - double zero_tolerance = 1e-9, - int max_iterations = 10) - { - Matrix Help = A; - - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - Help(i, j) = Help(i, j); - - vectors.resize(Help.size1(), Help.size2(), false); - - lambda.resize(Help.size1(), false); - - Matrix HelpDummy(Help.size1(), Help.size2()); - - bool is_converged = false; - - Matrix unity(Help.size1(), Help.size2()); - noalias(unity) = ZeroMatrix(Help.size1(), Help.size2()); - - for (unsigned int i = 0; i < Help.size1(); i++) - unity(i, i) = 1.0; - - Matrix V = unity; - - Matrix VDummy(Help.size1(), Help.size2()); - - Matrix Rotation(Help.size1(), Help.size2()); - - for (int iterations = 0; iterations < max_iterations; iterations++) { - is_converged = true; - - double a = 0.0; - - unsigned int index1 = 0; - - unsigned int index2 = 1; - - for (unsigned int i = 0; i < Help.size1(); i++) { - for (unsigned int j = (i + 1); j < Help.size2(); j++) { - if ((fabs(Help(i, j)) > a) && (fabs(Help(i, j)) > zero_tolerance)) { - a = fabs(Help(i, j)); - - index1 = i; - index2 = j; - - is_converged = false; - } - } - } - - // KRATOS_WATCH( Help ) - - if (is_converged) break; - - // Calculation of Rotationangle - - double gamma = (Help(index2, index2) - Help(index1, index1)) / (2 * Help(index1, index2)); - - double u = 1.0; - - if (fabs(gamma) > zero_tolerance && fabs(gamma) < (1 / zero_tolerance)) { - u = gamma / fabs(gamma) * 1.0 / (fabs(gamma) + sqrt(1.0 + gamma * gamma)); - } else { - if (fabs(gamma) >= (1.0 / zero_tolerance)) u = 0.5 / gamma; - } - - double c = 1.0 / (sqrt(1.0 + u * u)); - - double s = c * u; - - double teta = s / (1.0 + c); - - // Ratotion of the Matrix - HelpDummy = Help; - - HelpDummy(index2, index2) = Help(index2, index2) + u * Help(index1, index2); - HelpDummy(index1, index1) = Help(index1, index1) - u * Help(index1, index2); - HelpDummy(index1, index2) = 0.0; - HelpDummy(index2, index1) = 0.0; - - for (unsigned int i = 0; i < Help.size1(); i++) { - if ((i != index1) && (i != index2)) { - HelpDummy(index2, i) = Help(index2, i) + s * (Help(index1, i) - teta * Help(index2, i)); - HelpDummy(i, index2) = Help(index2, i) + s * (Help(index1, i) - teta * Help(index2, i)); - - HelpDummy(index1, i) = Help(index1, i) - s * (Help(index2, i) + teta * Help(index1, i)); - HelpDummy(i, index1) = Help(index1, i) - s * (Help(index2, i) + teta * Help(index1, i)); - } - } - - Help = HelpDummy; - - // Calculation of the eigenvectors V - Rotation = unity; - Rotation(index2, index1) = -s; - Rotation(index1, index2) = s; - Rotation(index1, index1) = c; - Rotation(index2, index2) = c; - - noalias(VDummy) = ZeroMatrix(Help.size1(), Help.size2()); - - for (unsigned int i = 0; i < Help.size1(); i++) { - for (unsigned int j = 0; j < Help.size1(); j++) { - for (unsigned int k = 0; k < Help.size1(); k++) { - VDummy(i, j) += V(i, k) * Rotation(k, j); - } - } - } - V = VDummy; - } - - if (!(is_converged)) { - std::cout << "########################################################" << std::endl; - std::cout << "Max_Iterations exceed in Jacobi-Seidel-Iteration (eigenvectors)" << std::endl; - std::cout << "########################################################" << std::endl; - } - - for (unsigned int i = 0; i < Help.size1(); i++) { - for (unsigned int j = 0; j < Help.size1(); j++) { - vectors(i, j) = V(j, i); - } - } - - for (unsigned int i = 0; i < Help.size1(); i++) - lambda(i) = Help(i, i); - } - - /** - * @} - */ - /** - * calculates Eigenvectors and the EigenValues of given square matrix A(3x3) - * The QR Algorithm with shifts is used - * @param A the given symmetric 3x3 real matrix - * @param V matrix to store the eigenvectors in rows - * @param d matrix to store the eigenvalues - */ - - /** - * converts a strain vector into a matrix. Strains are assumed to be stored - * in the following way: - * \f$ [ e11, e22, e33, 2*e12, 2*e23, 2*e13 ] \f$ for 3D case and - * \f$ [ e11, e22, 2*e12 ] \f$ fir 2D case. - * Hence the deviatoric components of the strain vector are divided by 2 - * while they are stored into the matrix - * @param Strains the given strain vector - * @return the corresponding strain tensor in matrix form - */ - static inline MatrixType StrainVectorToTensor(const VectorType& Strains) - { - KRATOS_TRY - - Matrix StrainTensor; - // KRATOS_WATCH( Strains ) - if (Strains.size() == 3) { - StrainTensor.resize(2, 2, false); - // KRATOS_WATCH( StrainTensor ) - StrainTensor(0, 0) = Strains[0]; - StrainTensor(0, 1) = 0.5 * Strains[2]; - StrainTensor(1, 0) = 0.5 * Strains[2]; - StrainTensor(1, 1) = Strains[1]; - } else if (Strains.size() == 6) { - StrainTensor.resize(3, 3, false); - StrainTensor(0, 0) = Strains[0]; - StrainTensor(0, 1) = 0.5 * Strains[3]; - StrainTensor(0, 2) = 0.5 * Strains[5]; - StrainTensor(1, 0) = 0.5 * Strains[3]; - StrainTensor(1, 1) = Strains[1]; - StrainTensor(1, 2) = 0.5 * Strains[4]; - StrainTensor(2, 0) = 0.5 * Strains[5]; - StrainTensor(2, 1) = 0.5 * Strains[4]; - StrainTensor(2, 2) = Strains[2]; - } - - // KRATOS_WATCH( StrainTensor ) - return StrainTensor; - KRATOS_CATCH("") - } - - static inline Vector TensorToStrainVector(const Matrix& Tensor) - { - KRATOS_TRY - Vector StrainVector; - - if (Tensor.size1() == 2) { - StrainVector.resize(3); - noalias(StrainVector) = ZeroVector(3); - StrainVector(0) = Tensor(0, 0); - StrainVector(1) = Tensor(1, 1); - StrainVector(2) = 2.00 * Tensor(0, 1); - } else if (Tensor.size1() == 3) { - StrainVector.resize(6); - noalias(StrainVector) = ZeroVector(6); - StrainVector(0) = Tensor(0, 0); - StrainVector(1) = Tensor(1, 1); - StrainVector(2) = Tensor(2, 2); - StrainVector(3) = 2.00 * Tensor(0, 1); - StrainVector(4) = 2.00 * Tensor(1, 2); - StrainVector(5) = 2.00 * Tensor(0, 2); - } - - return StrainVector; - KRATOS_CATCH("") - } - - /** - * Builds the norm of a gibven second order tensor - * @param Tensor the given second order tensor - * @return the norm of the given tensor - */ - static double NormTensor(Matrix& Tensor) - { - double result = 0.0; - for (unsigned int i = 0; i < Tensor.size1(); i++) - for (unsigned int j = 0; j < Tensor.size2(); j++) - result += Tensor(i, j) * Tensor(i, j); - - result = sqrt(result); - - return result; - } - - /** - * Transforms a given 6*1 Vector to a corresponing symmetric Tensor of second order (3*3) - * @param Vector the given vector - * @param Tensor the symmetric second order tensor - */ - static inline void VectorToTensor(const Vector& Stress, Matrix& Tensor) - { - if (Stress.size() == 6) { - Tensor.resize(3, 3); - Tensor(0, 0) = Stress(0); - Tensor(0, 1) = Stress(3); - Tensor(0, 2) = Stress(5); - Tensor(1, 0) = Stress(3); - Tensor(1, 1) = Stress(1); - Tensor(1, 2) = Stress(4); - Tensor(2, 0) = Stress(5); - Tensor(2, 1) = Stress(4); - Tensor(2, 2) = Stress(2); - } - if (Stress.size() == 3) { - Tensor.resize(2, 2); - Tensor(0, 0) = Stress(0); - Tensor(0, 1) = Stress(2); - Tensor(1, 0) = Stress(2); - Tensor(1, 1) = Stress(1); - } - } - - /** - * Transforms a given symmetric Tensor of second order (3*3) to a corresponing 6*1 Vector - * @param Tensor the given symmetric second order tensor - * @param Vector the vector - */ - static void TensorToVector(const Matrix& Tensor, Vector& Vector) - { - // if(Vector.size()!= 6) - unsigned int dim = Tensor.size1(); - if (dim == 3) { - Vector.resize(6, false); - Vector(0) = Tensor(0, 0); - Vector(1) = Tensor(1, 1); - Vector(2) = Tensor(2, 2); - Vector(3) = Tensor(0, 1); - Vector(4) = Tensor(1, 2); - Vector(5) = Tensor(2, 0); - } else if (dim == 2) { - Vector.resize(3, false); - Vector(0) = Tensor(0, 0); - Vector(1) = Tensor(1, 1); - Vector(2) = Tensor(0, 1); - } - } - - static inline void TensorToMatrix(FourthOrderTensorType& Tensor, Matrix& Matrix) - { - // Symmetric fourth order tensor: - // Cijkl = Cjilk - // Cijkl = Cklji - if (Tensor[0].size() == 3) { - // Fourth-order tensor whose components correspond to a 3x3 matrix - if (Matrix.size1() != 6 || Matrix.size2() != 6) Matrix.resize(6, 6, false); - Matrix(0, 0) = Tensor[0][0](0, 0); - Matrix(0, 1) = Tensor[0][0](1, 1); - Matrix(0, 2) = Tensor[0][0](2, 2); - Matrix(0, 3) = Tensor[0][0](0, 1); - Matrix(0, 4) = Tensor[0][0](0, 2); - Matrix(0, 5) = Tensor[0][0](1, 2); - - Matrix(1, 0) = Tensor[1][1](0, 0); - Matrix(1, 1) = Tensor[1][1](1, 1); - Matrix(1, 2) = Tensor[1][1](2, 2); - Matrix(1, 3) = Tensor[1][1](0, 1); - Matrix(1, 4) = Tensor[1][1](0, 2); - Matrix(1, 5) = Tensor[1][1](1, 2); - - Matrix(2, 0) = Tensor[2][2](0, 0); - Matrix(2, 1) = Tensor[2][2](1, 1); - Matrix(2, 2) = Tensor[2][2](2, 2); - Matrix(2, 3) = Tensor[2][2](0, 1); - Matrix(2, 4) = Tensor[2][2](0, 2); - Matrix(2, 5) = Tensor[2][2](1, 2); - - Matrix(3, 0) = Tensor[0][1](0, 0); - Matrix(3, 1) = Tensor[0][1](1, 1); - Matrix(3, 2) = Tensor[0][1](2, 2); - Matrix(3, 3) = Tensor[0][1](0, 1); - Matrix(3, 4) = Tensor[0][1](0, 2); - Matrix(3, 5) = Tensor[0][1](1, 2); - - Matrix(4, 0) = Tensor[0][2](0, 0); - Matrix(4, 1) = Tensor[0][2](1, 1); - Matrix(4, 2) = Tensor[0][2](2, 2); - Matrix(4, 3) = Tensor[0][2](0, 1); - Matrix(4, 4) = Tensor[0][2](0, 2); - Matrix(4, 5) = Tensor[0][2](1, 2); - - Matrix(5, 0) = Tensor[1][2](0, 0); - Matrix(5, 1) = Tensor[1][2](1, 1); - Matrix(5, 2) = Tensor[1][2](2, 2); - Matrix(5, 3) = Tensor[1][2](0, 1); - Matrix(5, 4) = Tensor[1][2](0, 2); - Matrix(5, 5) = Tensor[1][2](1, 2); - } else { - // Fourth-order tensor whose components correspond to a 2x2 matrix - if (Matrix.size1() != 3 || Matrix.size2() != 3) Matrix.resize(3, 3, false); - Matrix(0, 0) = Tensor[0][0](0, 0); - Matrix(0, 1) = Tensor[0][0](1, 1); - Matrix(0, 2) = Tensor[0][0](0, 1); - Matrix(1, 0) = Tensor[1][1](0, 0); - Matrix(1, 1) = Tensor[1][1](1, 1); - Matrix(1, 2) = Tensor[1][1](0, 1); - Matrix(2, 0) = Tensor[0][1](0, 0); - Matrix(2, 1) = Tensor[0][1](1, 1); - Matrix(2, 2) = Tensor[0][1](0, 1); - } - } - - /** - * Transforms a given 6*6 Matrix to a corresponing 4th order tensor - * @param Tensor the given Matrix - * @param Vector the Tensor - */ - static void MatrixToTensor(MatrixType& A, std::vector>& Tensor) - { - int help1 = 0; - int help2 = 0; - double coeff = 1.0; - - Tensor.resize(3); - - for (unsigned int i = 0; i < 3; i++) { - Tensor[i].resize(3); - for (unsigned int j = 0; j < 3; j++) { - Tensor[i][j].resize(3, 3, false); - noalias(Tensor[i][j]) = ZeroMatrix(3, 3); - for (unsigned int k = 0; k < 3; k++) - for (unsigned int l = 0; l < 3; l++) { - if (i == j) help1 = i; - else { - if ((i == 0 && j == 1) || (i == 1 && j == 0)) help1 = 3; - if ((i == 1 && j == 2) || (i == 2 && j == 1)) help1 = 4; - if ((i == 2 && j == 0) || (i == 0 && j == 2)) help1 = 5; - } - if (k == l) { - help2 = k; - coeff = 1.0; - } else { - coeff = 0.5; - if ((k == 0 && l == 1) || (k == 1 && l == 0)) help2 = 3; - if ((k == 1 && l == 2) || (k == 2 && l == 1)) help2 = 4; - if ((k == 2 && l == 0) || (k == 0 && l == 2)) help2 = 5; - } - - Tensor[i][j](k, l) = A(help1, help2) * coeff; - } - } - } - } - - /** - * Transforms a given 6*6 Matrix to a corresponing 4th order tensor - * @param Tensor the given Matrix - * @param Vector the Tensor - */ - static void MatrixToTensor(MatrixType& A, array_1d& Tensor) - { - int help1 = 0; - int help2 = 0; - double coeff = 1.0; - std::fill(Tensor.begin(), Tensor.end(), 0.0); - for (unsigned int i = 0; i < 3; i++) { - for (unsigned int j = 0; j < 3; j++) { - for (unsigned int k = 0; k < 3; k++) - for (unsigned int l = 0; l < 3; l++) { - if (i == j) help1 = i; - else { - if ((i == 0 && j == 1) || (i == 1 && j == 0)) help1 = 3; - if ((i == 1 && j == 2) || (i == 2 && j == 1)) help1 = 4; - if ((i == 2 && j == 0) || (i == 0 && j == 2)) help1 = 5; - } - if (k == l) { - help2 = k; - coeff = 1.0; - } else { - coeff = 0.5; - if ((k == 0 && l == 1) || (k == 1 && l == 0)) help2 = 3; - if ((k == 1 && l == 2) || (k == 2 && l == 1)) help2 = 4; - if ((k == 2 && l == 0) || (k == 0 && l == 2)) help2 = 5; - } - - Tensor[i * 27 + j * 9 + k * 3 + l] = A(help1, help2) * coeff; - } - } - } - } - - /** - * Transforms a given 4th order tensor to a corresponing 6*6 Matrix - * @param Tensor the given Tensor - * @param Vector the Matrix - */ - static void TensorToMatrix(std::vector>& Tensor, Matrix& Matrix) - { - int help1 = 0; - int help2 = 0; - int help3 = 0; - int help4 = 0; - double coeff = 1.0; - - if (Matrix.size1() != 6 || Matrix.size2() != 6) Matrix.resize(6, 6, false); - - for (unsigned int i = 0; i < 6; i++) - for (unsigned int j = 0; j < 6; j++) { - if (i < 3) { - help1 = i; - help2 = i; - } else { - if (i == 3) { - help1 = 0; - help2 = 1; - } - if (i == 4) { - help1 = 1; - help2 = 2; - } - if (i == 5) { - help1 = 2; - help2 = 0; - } - } - - if (j < 3) { - help3 = j; - help4 = j; - coeff = 1.0; - } else { - if (j == 3) { - help3 = 0; - help4 = 1; - } - if (j == 4) { - help3 = 1; - help4 = 2; - } - if (j == 5) { - help3 = 2; - help4 = 0; - } - coeff = 2.0; - } - - Matrix(i, j) = Tensor[help1][help2](help3, help4) * coeff; - } - } - - /** - * Transforms a given 4th order tensor to a corresponing 6*6 Matrix - * @param Tensor the given Tensor - * @param Vector the Matrix - */ - static void TensorToMatrix(const array_1d& Tensor, Matrix& Matrix) - { - if (Matrix.size1() != 6 || Matrix.size2() != 6) Matrix.resize(6, 6, false); - - Matrix(0, 0) = Tensor[0]; - Matrix(0, 1) = Tensor[4]; - Matrix(0, 2) = Tensor[8]; - Matrix(0, 3) = 2.0 * Tensor[1]; - Matrix(0, 4) = 2.0 * Tensor[5]; - Matrix(0, 5) = 2.0 * Tensor[6]; - - Matrix(1, 0) = Tensor[36]; - Matrix(1, 1) = Tensor[40]; - Matrix(1, 2) = Tensor[44]; - Matrix(1, 3) = 2.0 * Tensor[37]; - Matrix(1, 4) = 0.0 * Tensor[41]; - Matrix(1, 5) = 0.0 * Tensor[42]; - - Matrix(2, 0) = Tensor[72]; - Matrix(2, 1) = Tensor[76]; - Matrix(2, 2) = Tensor[80]; - Matrix(2, 3) = 2.0 * Tensor[73]; - Matrix(2, 4) = 2.0 * Tensor[77]; - Matrix(2, 5) = 2.0 * Tensor[78]; - - Matrix(3, 0) = Tensor[9]; - Matrix(3, 1) = Tensor[13]; - Matrix(3, 2) = Tensor[18]; - Matrix(3, 3) = 2.0 * Tensor[10]; - Matrix(3, 4) = 2.0 * Tensor[14]; - Matrix(3, 5) = 2.0 * Tensor[15]; - - Matrix(4, 0) = Tensor[45]; - Matrix(4, 1) = Tensor[49]; - Matrix(4, 2) = Tensor[53]; - Matrix(4, 3) = 2.0 * Tensor[46]; - Matrix(4, 4) = 0.0 * Tensor[50]; - Matrix(4, 5) = 0.0 * Tensor[51]; - - Matrix(5, 0) = Tensor[54]; - Matrix(5, 1) = Tensor[58]; - Matrix(5, 2) = Tensor[62]; - Matrix(5, 3) = 2.0 * Tensor[55]; - Matrix(5, 4) = 2.0 * Tensor[59]; - Matrix(5, 5) = 2.0 * Tensor[60]; - } - - /** - * Generates the fourth order deviatoric unity tensor - * @param Unity the deviatoric unity (will be overwritten) - */ - static void DeviatoricUnity(std::vector>& Unity) - { - Unity.resize(3); - - Matrix kronecker(3, 3); - noalias(kronecker) = ZeroMatrix(3, 3); - for (unsigned int i = 0; i < 3; i++) { - kronecker(i, i) = 1; - } - - for (unsigned int i = 0; i < 3; i++) { - Unity[i].resize(3); - for (unsigned int j = 0; j < 3; j++) { - Unity[i][j].resize(3, 3, false); - noalias(Unity[i][j]) = ZeroMatrix(3, 3); - - for (unsigned int k = 0; k < 3; k++) { - for (unsigned int l = 0; l < 3; l++) { - Unity[i][j](k, l) = kronecker(i, k) * kronecker(j, l) - - 1.0 / 3.0 * kronecker(i, j) * kronecker(k, l); - } - } - } - } - } - - /** - * Generates the fourth order deviatoric unity tensor - * @param Unity the deviatoric unity (will be overwritten) - */ - static void DeviatoricUnity(array_1d& Unity) - { - Matrix kronecker(3, 3); - noalias(kronecker) = ZeroMatrix(3, 3); - for (unsigned int i = 0; i < 3; i++) { - kronecker(i, i) = 1; - } - - for (unsigned int i = 0; i < 3; i++) - for (unsigned int j = 0; j < 3; j++) - for (unsigned int k = 0; k < 3; k++) - for (unsigned int l = 0; l < 3; l++) - Unity[27 * i + 9 * j + 3 * k + l] = kronecker(i, k) * kronecker(j, l) - - 1.0 / 3.0 * kronecker(i, j) * kronecker(k, l); - } - - /** - * Performs clipping on the two polygons clipping_points and subjected_points (the technique - * used is Sutherland-Hodgman clipping) and returns the overlapping polygon result_points. The - * method works in 3D. Both polygons have to be convex, but they can be slightly perturbated in - * 3D space, this allows for performing clipping on two interpolated interfaces - * @param clipping_points vertices of clipping polygon - * @param subjected_points vertices of subjected polygon - * @param result_points vertices of overlapping polygon - * @return false= no overlapping polygon, true= overlapping polygon found - */ - static bool Clipping(std::vector& clipping_points, - std::vector& subjected_points, - std::vector& result_points, - double tolerance) - { - result_points = subjected_points; - Vector actual_edge(3); - Vector actual_normal(3); - std::vector temp_results; - bool is_visible = false; - for (unsigned int clipp_edge = 0; clipp_edge < clipping_points.size(); clipp_edge++) { - temp_results.clear(); - unsigned int index_clipp_2 = 0; - if (clipp_edge < (clipping_points.size() - 1)) index_clipp_2 = clipp_edge + 1; - // define clipping edge vector - noalias(actual_edge) = *(clipping_points[clipp_edge]) - *(clipping_points[index_clipp_2]); - noalias(actual_edge) = actual_edge / sqrt(inner_prod(actual_edge, actual_edge)); - - // define normal on clipping-edge vector towards visible side - if (clipp_edge < (clipping_points.size() - 2)) - actual_normal = *(clipping_points[clipp_edge + 2]) - - (*(clipping_points[clipp_edge]) + - actual_edge * inner_prod((*(clipping_points[clipp_edge + 2]) - - *(clipping_points[clipp_edge])), - actual_edge)); - else if (clipp_edge < (clipping_points.size() - 1)) - actual_normal = - *(clipping_points[0]) - - (*(clipping_points[clipp_edge]) + - actual_edge * inner_prod((*(clipping_points[0]) - *(clipping_points[clipp_edge])), actual_edge)); - else - actual_normal = - *(clipping_points[1]) - - (*(clipping_points[clipp_edge]) + - actual_edge * inner_prod((*(clipping_points[1]) - *(clipping_points[clipp_edge])), actual_edge)); - - noalias(actual_normal) = actual_normal / (sqrt(inner_prod(actual_normal, actual_normal))); - - // test if the first point is visible or unvisible - if (inner_prod((*(result_points[0]) - *(clipping_points[clipp_edge])), actual_normal) > tolerance) { - is_visible = true; - } else { - is_visible = false; - } - - for (unsigned int subj_edge = 0; subj_edge < result_points.size(); subj_edge++) { - unsigned int index_subj_2 = 0; - - if (subj_edge < (result_points.size() - 1)) index_subj_2 = subj_edge + 1; - - // Test whether the points of the actual subj_edge lay on clipp_edge - if (fabs(inner_prod((*(result_points[subj_edge]) - (*(clipping_points[clipp_edge]))), - actual_normal)) <= tolerance) { - temp_results.push_back(result_points[subj_edge]); - if (inner_prod((*(result_points[index_subj_2]) - *(clipping_points[clipp_edge])), - actual_normal) > tolerance) - is_visible = true; - else is_visible = false; - - continue; - } - // Calculate minimal distance between the two points - Vector b(2); - b(0) = -inner_prod((*(result_points[index_subj_2]) - *(result_points[subj_edge])), - (*(result_points[subj_edge]) - *(clipping_points[clipp_edge]))); - b(1) = inner_prod((*(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge])), - (*(result_points[subj_edge]) - *(clipping_points[clipp_edge]))); - Matrix A(2, 2); - A(0, 0) = inner_prod((*(result_points[index_subj_2]) - *(result_points[subj_edge])), - (*(result_points[index_subj_2]) - *(result_points[subj_edge]))); - A(0, 1) = -inner_prod((*(result_points[index_subj_2]) - *(result_points[subj_edge])), - (*(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge]))); - A(1, 0) = A(0, 1); - A(1, 1) = inner_prod(*(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge]), - *(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge])); - Vector coeff(2); - coeff(0) = 1.0 / A(0, 0) * - (b(0) - A(0, 1) / (A(1, 1) - A(0, 1) * A(1, 0) / A(0, 0)) * - (b(1) - b(0) * A(1, 0) / A(0, 0))); - coeff(1) = 1.0 / (A(1, 1) - A(0, 1) * A(1, 0) / A(0, 0)) * (b(1) - b(0) * A(1, 0) / A(0, 0)); - - // TEST on distance to endpoints of the line - Vector dist_vec(3); - noalias(dist_vec) = - *(result_points[subj_edge]) + - coeff(0) * (*(result_points[index_subj_2]) - *(result_points[subj_edge])) - - (*(clipping_points[clipp_edge]) + - coeff(1) * (*(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge]))); - - if (coeff(0) > tolerance && coeff(0) < (1 - tolerance) && - (sqrt(inner_prod(dist_vec, dist_vec)) < tolerance)) { - if (is_visible) temp_results.push_back(result_points[subj_edge]); - - temp_results.push_back(new Point( - (*(clipping_points[clipp_edge]) + - coeff(1) * (*(clipping_points[index_clipp_2]) - *(clipping_points[clipp_edge]))))); - - is_visible = !is_visible; - - continue; - } - if (is_visible) temp_results.push_back(result_points[subj_edge]); - } - result_points = temp_results; - } - if (result_points.size() == 0) return false; - else return true; - } - [[nodiscard]] static std::vector CalculateDeterminants(const std::vector& rMatrices); }; // class GeoMechanicsMathUtilities diff --git a/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.cpp b/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.cpp index baf741afb2bf..c6c0fcd2f944 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.cpp +++ b/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.cpp @@ -7,12 +7,13 @@ // // License: geo_mechanics_application/license.txt // -// Main authors: Richard Faasse +// Main authors: Richard Faasse, +// Gennady Markelov // #include "stress_strain_utilities.h" -#include "custom_utilities/math_utilities.h" #include "geo_mechanics_application_constants.h" +#include "utilities/math_utils.h" #include namespace Kratos @@ -152,4 +153,26 @@ Matrix StressStrainUtilities::CalculateGreenLagrangeStrainTensor(const Matrix& r IdentityMatrix(rDeformationGradient.size1())); } +Vector StressStrainUtilities::CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements) +{ + return prod(rB, rDisplacements); +} + +std::vector StressStrainUtilities::CalculateStrains(const std::vector& rDeformationGradients, + const std::vector& rBs, + const Vector& rDisplacements, + bool UseHenckyStrain, + std::size_t VoigtSize) +{ + std::vector result; + std::transform( + rDeformationGradients.begin(), rDeformationGradients.end(), rBs.begin(), std::back_inserter(result), + [&rDisplacements, UseHenckyStrain, VoigtSize](const auto& rDeformationGradient, const auto& rB) { + return UseHenckyStrain ? CalculateHenckyStrain(rDeformationGradient, VoigtSize) + : CalculateCauchyStrain(rB, rDisplacements); + }); + + return result; +} + } // namespace Kratos diff --git a/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.h b/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.h index 1e3e1c5d2aa6..6433ae8d62fb 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.h +++ b/applications/GeoMechanicsApplication/custom_utilities/stress_strain_utilities.h @@ -8,7 +8,9 @@ // License: geo_mechanics_application/license.txt // // Main authors: JMCarbonell, -// Vahid Galavi +// Vahid Galavi, +// Richard Faasse, +// Gennady Markelov // #pragma once @@ -32,6 +34,12 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) StressStrainUtilities static double CalculateVonMisesStrain(const Vector& rStrainVector); static Vector CalculateHenckyStrain(const Matrix& rDeformationGradient, size_t VoigtSize); static Matrix CalculateGreenLagrangeStrainTensor(const Matrix& rDeformationGradient); + static Vector CalculateCauchyStrain(const Matrix& rB, const Vector& rDisplacements); + static std::vector CalculateStrains(const std::vector& rDeformationGradients, + const std::vector& rBs, + const Vector& rDisplacements, + bool UseHenckyStrain, + std::size_t VoigtSize); private: static double CalculateQMohrCoulomb(const Vector& rStressVector, double C, double Phi); diff --git a/applications/GeoMechanicsApplication/custom_utilities/transport_equation_utilities.hpp b/applications/GeoMechanicsApplication/custom_utilities/transport_equation_utilities.hpp index cf85fefbdb35..0b355334f9d0 100644 --- a/applications/GeoMechanicsApplication/custom_utilities/transport_equation_utilities.hpp +++ b/applications/GeoMechanicsApplication/custom_utilities/transport_equation_utilities.hpp @@ -16,6 +16,7 @@ // Application includes #include "custom_retention/retention_law.h" +#include "custom_utilities/stress_strain_utilities.h" #include "geo_mechanics_application_variables.h" namespace Kratos @@ -30,24 +31,21 @@ class GeoTransportEquationUtilities double DynamicViscosityInverse, const BoundedMatrix& rMaterialPermeabilityMatrix, double RelativePermeability, - double PermeabilityUpdateFactor, double IntegrationCoefficient) { - return CalculatePermeabilityMatrix(rGradNpT, DynamicViscosityInverse, - rMaterialPermeabilityMatrix, RelativePermeability, - PermeabilityUpdateFactor, IntegrationCoefficient); + return CalculatePermeabilityMatrix(rGradNpT, DynamicViscosityInverse, rMaterialPermeabilityMatrix, + RelativePermeability, IntegrationCoefficient); } static inline Matrix CalculatePermeabilityMatrix(const Matrix& rGradNpT, double DynamicViscosityInverse, const Matrix& rMaterialPermeabilityMatrix, double RelativePermeability, - double PermeabilityUpdateFactor, double IntegrationCoefficient) { return -PORE_PRESSURE_SIGN_FACTOR * DynamicViscosityInverse * prod(rGradNpT, Matrix(prod(rMaterialPermeabilityMatrix, trans(rGradNpT)))) * - RelativePermeability * PermeabilityUpdateFactor * IntegrationCoefficient; + RelativePermeability * IntegrationCoefficient; } template @@ -100,18 +98,100 @@ class GeoTransportEquationUtilities static Vector CalculateDegreesSaturation(const Vector& rPressureSolution, const Matrix& rNContainer, const std::vector& rRetentionLawVector, - const Properties& rProp, - const ProcessInfo& rCurrentProcessInfo) + const Properties& rProp) { - RetentionLaw::Parameters retention_parameters(rProp, rCurrentProcessInfo); + RetentionLaw::Parameters retention_parameters(rProp); Vector result(rRetentionLawVector.size()); for (unsigned int g_point = 0; g_point < rRetentionLawVector.size(); ++g_point) { - const double fluid_pressure = inner_prod(row(rNContainer, g_point), rPressureSolution); + const double fluid_pressure = CalculateFluidPressure(row(rNContainer, g_point), rPressureSolution); retention_parameters.SetFluidPressure(fluid_pressure); result(g_point) = rRetentionLawVector[g_point]->CalculateSaturation(retention_parameters); } return result; } + [[nodiscard]] static double CalculateFluidPressure(const Vector& rN, const Vector& rPressureVector) + { + return inner_prod(rN, rPressureVector); + } + + [[nodiscard]] static std::vector CalculateFluidPressures(const Matrix& rNContainer, const Vector& rPressureVector) + { + auto result = std::vector{}; + for (auto i = std::size_t{0}; i < rNContainer.size1(); ++i) { + result.emplace_back(CalculateFluidPressure(row(rNContainer, i), rPressureVector)); + } + return result; + } + + [[nodiscard]] static double CalculateBiotModulusInverse(double BiotCoefficient, + double DegreeOfSaturation, + double DerivativeOfSaturation, + const Properties& rProperties) + { + const auto bulk_modulus_fluid = rProperties[IGNORE_UNDRAINED] ? TINY : rProperties[BULK_MODULUS_FLUID]; + double result = (BiotCoefficient - rProperties[POROSITY]) / rProperties[BULK_MODULUS_SOLID] + + rProperties[POROSITY] / bulk_modulus_fluid; + + result *= DegreeOfSaturation; + result -= DerivativeOfSaturation * rProperties[POROSITY]; + + return result; + } + + [[nodiscard]] static double CalculateBulkModulus(const Matrix& rConstitutiveMatrix) + { + KRATOS_ERROR_IF(rConstitutiveMatrix.size1() == 0) + << "Constitutive matrix is empty, aborting bulk modulus calculation.\n"; + const SizeType index_G = rConstitutiveMatrix.size1() - 1; + return rConstitutiveMatrix(0, 0) - (4.0 / 3.0) * rConstitutiveMatrix(index_G, index_G); + } + + [[nodiscard]] static std::vector CalculateBiotCoefficients(const std::vector& rConstitutiveMatrices, + const Properties& rProperties) + { + std::vector result; + std::transform(rConstitutiveMatrices.begin(), rConstitutiveMatrices.end(), + std::back_inserter(result), [&rProperties](const Matrix& rConstitutiveMatrix) { + return CalculateBiotCoefficient(rConstitutiveMatrix, rProperties); + }); + + return result; + } + + [[nodiscard]] static std::vector CalculatePermeabilityUpdateFactors(const std::vector& rStrainVectors, + const Properties& rProperties) + { + auto result = std::vector{}; + std::transform(rStrainVectors.cbegin(), rStrainVectors.cend(), std::back_inserter(result), + [&rProperties](const auto& rStrainVector) { + return CalculatePermeabilityUpdateFactor(rStrainVector, rProperties); + }); + return result; + } + +private: + [[nodiscard]] static double CalculateBiotCoefficient(const Matrix& rConstitutiveMatrix, + const Properties& rProperties) + { + return rProperties.Has(BIOT_COEFFICIENT) + ? rProperties[BIOT_COEFFICIENT] + : 1.0 - CalculateBulkModulus(rConstitutiveMatrix) / rProperties[BULK_MODULUS_SOLID]; + } + + [[nodiscard]] static double CalculatePermeabilityUpdateFactor(const Vector& rStrainVector, + const Properties& rProperties) + { + if (rProperties[PERMEABILITY_CHANGE_INVERSE_FACTOR] > 0.0) { + const double InverseCK = rProperties[PERMEABILITY_CHANGE_INVERSE_FACTOR]; + const double epsV = StressStrainUtilities::CalculateTrace(rStrainVector); + const double ePrevious = rProperties[POROSITY] / (1.0 - rProperties[POROSITY]); + const double eCurrent = (1.0 + ePrevious) * std::exp(epsV) - 1.0; + const double permLog10 = (eCurrent - ePrevious) * InverseCK; + return std::pow(10.0, permLog10); + } + + return 1.0; + } }; /* Class GeoTransportEquationUtilities*/ } /* namespace Kratos.*/ diff --git a/applications/GeoMechanicsApplication/geo_mechanics_application.cpp b/applications/GeoMechanicsApplication/geo_mechanics_application.cpp index 8671570562b2..7047c6d9fea4 100644 --- a/applications/GeoMechanicsApplication/geo_mechanics_application.cpp +++ b/applications/GeoMechanicsApplication/geo_mechanics_application.cpp @@ -262,6 +262,9 @@ void KratosGeoMechanicsApplication::Register() { KRATOS_REGISTER_CONDITION("PwNormalFluxCondition3D3N", mPwNormalFluxCondition3D3N) KRATOS_REGISTER_CONDITION("PwNormalFluxCondition3D4N", mPwNormalFluxCondition3D4N) + KRATOS_REGISTER_CONDITION("PwPointFluxCondition2D1N", mPwPointFluxCondition2D1N) + KRATOS_REGISTER_CONDITION("PwPointFluxCondition3D1N", mPwPointFluxCondition3D1N) + KRATOS_REGISTER_CONDITION("UPwFaceLoadInterfaceCondition2D2N", mUPwFaceLoadInterfaceCondition2D2N) KRATOS_REGISTER_CONDITION("UPwFaceLoadInterfaceCondition3D4N", mUPwFaceLoadInterfaceCondition3D4N) KRATOS_REGISTER_CONDITION("UPwNormalFluxInterfaceCondition2D2N", mUPwNormalFluxInterfaceCondition2D2N) @@ -352,8 +355,6 @@ void KratosGeoMechanicsApplication::Register() { KRATOS_REGISTER_CONSTITUTIVE_LAW("LinearElastic2DBeamLaw", mLinearElastic2DBeamLaw) - KRATOS_REGISTER_CONSTITUTIVE_LAW("GeoThermalDispersion2DLaw", mGeoThermalDispersion2DLaw) - KRATOS_REGISTER_CONSTITUTIVE_LAW("GeoThermalDispersion3DLaw", mGeoThermalDispersion3DLaw) //Register Variables KRATOS_REGISTER_VARIABLE( VELOCITY_COEFFICIENT ) @@ -378,6 +379,7 @@ void KratosGeoMechanicsApplication::Register() { KRATOS_REGISTER_VARIABLE( DT_TEMPERATURE_COEFFICIENT ) KRATOS_REGISTER_VARIABLE( DT_TEMPERATURE ) KRATOS_REGISTER_VARIABLE( NORMAL_HEAT_FLUX ) + KRATOS_REGISTER_VARIABLE( THERMAL_LAW_NAME) // Variables for Micro-Climate boundary KRATOS_REGISTER_VARIABLE( AIR_TEMPERATURE ) diff --git a/applications/GeoMechanicsApplication/geo_mechanics_application.h b/applications/GeoMechanicsApplication/geo_mechanics_application.h index 27cc7420d82b..84853a25c53a 100644 --- a/applications/GeoMechanicsApplication/geo_mechanics_application.h +++ b/applications/GeoMechanicsApplication/geo_mechanics_application.h @@ -48,6 +48,7 @@ #include "custom_conditions/surface_load_3D_diff_order_condition.hpp" #include "custom_conditions/surface_normal_fluid_flux_3D_diff_order_condition.hpp" #include "custom_conditions/surface_normal_load_3D_diff_order_condition.hpp" +#include "custom_conditions/Pw_point_flux_condition.hpp" #include "custom_conditions/thermal_point_flux_condition.h" // Geometries @@ -131,7 +132,6 @@ #include "custom_constitutive/small_strain_umat_2D_plane_strain_law.hpp" #include "custom_constitutive/small_strain_umat_3D_interface_law.hpp" #include "custom_constitutive/small_strain_umat_3D_law.hpp" -#include "custom_constitutive/thermal_dispersion_law.h" namespace Kratos { @@ -504,6 +504,10 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) KratosGeoMechanicsApplication : publ const PwNormalFluxCondition<3,3> mPwNormalFluxCondition3D3N{ 0, Kratos::make_shared< Triangle3D3 >(Condition::GeometryType::PointsArrayType(3)) }; const PwNormalFluxCondition<3,4> mPwNormalFluxCondition3D4N{ 0, Kratos::make_shared< Quadrilateral3D4 >(Condition::GeometryType::PointsArrayType(4)) }; + const PwPointFluxCondition<2, 1> mPwPointFluxCondition2D1N{ 0, Kratos::make_shared>(Condition::GeometryType::PointsArrayType(1)) }; + const PwPointFluxCondition<3, 1> mPwPointFluxCondition3D1N{ 0, Kratos::make_shared>(Condition::GeometryType::PointsArrayType(1)) }; + + const UPwFaceLoadInterfaceCondition<2,2> mUPwFaceLoadInterfaceCondition2D2N{ 0, Kratos::make_shared< Line2D2 >(Condition::GeometryType::PointsArrayType(2)) }; const UPwFaceLoadInterfaceCondition<3,4> mUPwFaceLoadInterfaceCondition3D4N{ 0, Kratos::make_shared< QuadrilateralInterface3D4 >(Condition::GeometryType::PointsArrayType(4)) }; @@ -598,9 +602,6 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) KratosGeoMechanicsApplication : publ const LinearElastic2DBeamLaw mLinearElastic2DBeamLaw; - const GeoThermalDispersionLaw mGeoThermalDispersion2DLaw{ConstitutiveLaw::SizeType(2)}; - const GeoThermalDispersionLaw mGeoThermalDispersion3DLaw{ConstitutiveLaw::SizeType(3)}; - ///@} }; // Class KratosGeoMechanicsApplication diff --git a/applications/GeoMechanicsApplication/geo_mechanics_application_variables.cpp b/applications/GeoMechanicsApplication/geo_mechanics_application_variables.cpp index 402e94099616..5ceec4b4439d 100644 --- a/applications/GeoMechanicsApplication/geo_mechanics_application_variables.cpp +++ b/applications/GeoMechanicsApplication/geo_mechanics_application_variables.cpp @@ -38,6 +38,7 @@ KRATOS_CREATE_VARIABLE( double, SOLID_COMPRESSIBILITY ) KRATOS_CREATE_VARIABLE( double, DT_TEMPERATURE_COEFFICIENT ) KRATOS_CREATE_VARIABLE( double, DT_TEMPERATURE ) KRATOS_CREATE_VARIABLE( double, NORMAL_HEAT_FLUX ) +KRATOS_CREATE_VARIABLE( std::string, THERMAL_LAW_NAME ) // Variables for Micro-Climate boundary KRATOS_CREATE_VARIABLE( double, AIR_TEMPERATURE ) diff --git a/applications/GeoMechanicsApplication/geo_mechanics_application_variables.h b/applications/GeoMechanicsApplication/geo_mechanics_application_variables.h index 24249ab2d1b9..16ef72753b7e 100644 --- a/applications/GeoMechanicsApplication/geo_mechanics_application_variables.h +++ b/applications/GeoMechanicsApplication/geo_mechanics_application_variables.h @@ -65,6 +65,7 @@ namespace Kratos KRATOS_DEFINE_APPLICATION_VARIABLE( GEO_MECHANICS_APPLICATION, double, DT_TEMPERATURE_COEFFICIENT ) KRATOS_DEFINE_APPLICATION_VARIABLE( GEO_MECHANICS_APPLICATION, double, DT_TEMPERATURE ) KRATOS_DEFINE_APPLICATION_VARIABLE( GEO_MECHANICS_APPLICATION, double, NORMAL_HEAT_FLUX ) + KRATOS_DEFINE_APPLICATION_VARIABLE( GEO_MECHANICS_APPLICATION, std::string, THERMAL_LAW_NAME ) // Variables for Micro-Climate boundary KRATOS_DEFINE_APPLICATION_VARIABLE( GEO_MECHANICS_APPLICATION, double, AIR_TEMPERATURE ) diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_axisymmetric_stress_state.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_axisymmetric_stress_state.cpp index 8e6bb7ccf8c4..a450f3c3a393 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_axisymmetric_stress_state.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_axisymmetric_stress_state.cpp @@ -100,4 +100,29 @@ KRATOS_TEST_CASE_IN_SUITE(TestCalculateGreenLagrangeStrainThrows, KratosGeoMecha "not implemented for axisymmetric configurations.") } +KRATOS_TEST_CASE_IN_SUITE(AxisymmetricStressState_GivesCorrectVoigtVector, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + Vector voigt_vector = p_stress_state_policy->GetVoigtVector(); + + Vector expected_voigt_vector(4); + expected_voigt_vector <<= 1.0, 1.0, 1.0, 0.0; + KRATOS_EXPECT_VECTOR_NEAR(voigt_vector, expected_voigt_vector, 1.E-10) +} + +KRATOS_TEST_CASE_IN_SUITE(AxisymmetricStressState_GivesCorrectVoigtSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetVoigtSize(), VOIGT_SIZE_2D_PLANE_STRAIN); +} + +KRATOS_TEST_CASE_IN_SUITE(AxisymmetricStressState_GivesCorrectStressTensorSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetStressTensorSize(), STRESS_TENSOR_SIZE_2D); +} + } // namespace Kratos::Testing diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_constitutive_law_set6.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_constitutive_law_set6.cpp new file mode 100644 index 000000000000..f73b3448ea8c --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_constitutive_law_set6.cpp @@ -0,0 +1,53 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Gennady Markelov +// + +#include "custom_utilities/constitutive_law_utilities.hpp" +#include "includes/checks.h" +#include "testing/testing.h" +#include + +using namespace Kratos; + +namespace Kratos::Testing +{ + +KRATOS_TEST_CASE_IN_SUITE(SetSixConstitutiveParametersCorrectResults, KratosGeoMechanicsFastSuite) +{ + ConstitutiveLaw::Parameters ConstitutiveParameters; + + Vector strain_vector(3); + strain_vector <<= 1.0, 2.0, 3.0; + Matrix constitutive_matrix = IdentityMatrix(5, 5); + Vector N(3); + N <<= 0.1, 0.2, 0.5; + const Matrix shape_functions_derivatives = ScalarMatrix(3, 3, 5.0); + const Matrix deformation_gradient_F = ScalarMatrix(3, 3, 10.0); + constexpr double determinant_of_F = 10.0; + ConstitutiveLawUtilities::SetConstitutiveParameters( + ConstitutiveParameters, strain_vector, constitutive_matrix, N, shape_functions_derivatives, + deformation_gradient_F, determinant_of_F); + + KRATOS_CHECK_VECTOR_NEAR(ConstitutiveParameters.GetStrainVector(), strain_vector, 1e-12) + + KRATOS_CHECK_MATRIX_NEAR(ConstitutiveParameters.GetConstitutiveMatrix(), constitutive_matrix, 1e-12) + + KRATOS_CHECK_VECTOR_NEAR(ConstitutiveParameters.GetShapeFunctionsValues(), N, 1e-12) + + KRATOS_CHECK_MATRIX_NEAR(ConstitutiveParameters.GetShapeFunctionsDerivatives(), + shape_functions_derivatives, 1e-12) + + KRATOS_CHECK_MATRIX_NEAR(ConstitutiveParameters.GetDeformationGradientF(), deformation_gradient_F, 1e-12) + + KRATOS_CHECK_NEAR(ConstitutiveParameters.GetDeterminantF(), determinant_of_F, 1e-12); +} + +} // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_equation_of_motion.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_equation_of_motion.cpp index 8f92fdba1370..ac2b064cba53 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_equation_of_motion.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_equation_of_motion.cpp @@ -158,4 +158,29 @@ KRATOS_TEST_CASE_IN_SUITE(CalculateDampingMatrixGivesCorrectResults, KratosGeoMe KRATOS_CHECK_MATRIX_NEAR(damping_matrix, expected_damping_matrix, 1e-4) } +KRATOS_TEST_CASE_IN_SUITE(CalculateStiffnessMatrixGivesCorrectResults, KratosGeoMechanicsFastSuite) +{ + constexpr std::size_t voigt_size = 4; + constexpr std::size_t n = 3; + + const Matrix b = ScalarMatrix(voigt_size, n, 0.5); + std::vector b_matrices; + b_matrices.push_back(b); + b_matrices.push_back(b); + + const Matrix constitutive = ScalarMatrix(voigt_size, voigt_size, 2.0); + std::vector constitutive_matrices; + constitutive_matrices.push_back(constitutive); + constitutive_matrices.push_back(constitutive); + + std::vector integration_coefficients{1.0, 2.0}; + + auto stiffness_matrix = GeoEquationOfMotionUtilities::CalculateStiffnessMatrix( + b_matrices, constitutive_matrices, integration_coefficients); + + const auto expected_stiffness_matrix = ScalarMatrix(n, n, 24.0); + + KRATOS_CHECK_MATRIX_NEAR(stiffness_matrix, expected_stiffness_matrix, 1e-4) +} + } // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_fluid_pressure.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_fluid_pressure.cpp new file mode 100644 index 000000000000..3aa8daa4c5cf --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_fluid_pressure.cpp @@ -0,0 +1,36 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Gennady Markelov +// + +#include "boost/numeric/ublas/assignment.hpp" +#include "custom_utilities/transport_equation_utilities.hpp" +#include "includes/checks.h" +#include "testing/testing.h" + +using namespace Kratos; + +namespace Kratos::Testing +{ + +KRATOS_TEST_CASE_IN_SUITE(CalculateFluidPressureGivesCorrectResults, KratosGeoMechanicsFastSuite) +{ + Vector N(5); + N <<= 1.0, 2.0, 3.0, 4.0, 5.0; + + Vector pressure_vector(5); + pressure_vector <<= 0.5, 0.7, 0.8, 0.9, 0.4; + + auto fluid_pressure = GeoTransportEquationUtilities::CalculateFluidPressure(N, pressure_vector); + double expected_value = 9.9; + KRATOS_CHECK_NEAR(fluid_pressure, expected_value, 1e-12); +} + +} // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_math_utilities.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_math_utilities.cpp index 47487c2cdaa1..16f693e17894 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_math_utilities.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_math_utilities.cpp @@ -13,6 +13,7 @@ #include "custom_utilities/math_utilities.h" #include "includes/checks.h" #include "testing/testing.h" +#include "includes/checks.h" namespace Kratos::Testing { diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_permeability_matrix.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_permeability_matrix.cpp index 10e3860afe44..1463faa36023 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_permeability_matrix.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_permeability_matrix.cpp @@ -41,8 +41,8 @@ KRATOS_TEST_CASE_IN_SUITE(CalculatePermeabilityMatrix2D3NGivesCorrectResults, Kr const double RelativePermeability = 0.02; const double PermeabilityUpdateFactor = 1.5; PermeabilityMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix<2, 3>( - GradNpT, DynamicViscosityInverse, MaterialPermeabilityMatrix, RelativePermeability, - PermeabilityUpdateFactor, IntegrationCoefficient); + GradNpT, DynamicViscosityInverse, MaterialPermeabilityMatrix, + RelativePermeability * PermeabilityUpdateFactor, IntegrationCoefficient); BoundedMatrix PMatrix; // clang-format off @@ -76,8 +76,8 @@ KRATOS_TEST_CASE_IN_SUITE(CalculatePermeabilityMatrix3D4NGivesCorrectResults, Kr const double RelativePermeability = 0.1; const double PermeabilityUpdateFactor = 2.0; PermeabilityMatrix = GeoTransportEquationUtilities::CalculatePermeabilityMatrix<3, 4>( - GradNpT, DynamicViscosityInverse, MaterialPermeabilityMatrix, RelativePermeability, - PermeabilityUpdateFactor, IntegrationCoefficient); + GradNpT, DynamicViscosityInverse, MaterialPermeabilityMatrix, + RelativePermeability * PermeabilityUpdateFactor, IntegrationCoefficient); BoundedMatrix PMatrix; // clang-format off diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_plane_strain_stress_state.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_plane_strain_stress_state.cpp index 646abcce33ce..fabe96f72f5f 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_plane_strain_stress_state.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_plane_strain_stress_state.cpp @@ -101,4 +101,29 @@ KRATOS_TEST_CASE_IN_SUITE(PlaneStrainStressState_GivesCorrectClone, KratosGeoMec KRATOS_EXPECT_NE(dynamic_cast(p_clone.get()), nullptr); } +KRATOS_TEST_CASE_IN_SUITE(PlaneStrainStressState_GivesCorrectVoigtVector, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + Vector voigt_vector = p_stress_state_policy->GetVoigtVector(); + + Vector expected_voigt_vector(4); + expected_voigt_vector <<= 1.0, 1.0, 1.0, 0.0; + KRATOS_EXPECT_VECTOR_NEAR(voigt_vector, expected_voigt_vector, 1.E-10) +} + +KRATOS_TEST_CASE_IN_SUITE(PlaneStrainStressState_GivesCorrectVoigtSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetVoigtSize(), VOIGT_SIZE_2D_PLANE_STRAIN); +} + +KRATOS_TEST_CASE_IN_SUITE(PlaneStrainStressState_GivesCorrectStressTensorSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetStressTensorSize(), STRESS_TENSOR_SIZE_2D); +} + } // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_stress_strain_utitlities.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_stress_strain_utitlities.cpp index 8a8834e860f3..7ecff946b4fa 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_stress_strain_utitlities.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_stress_strain_utitlities.cpp @@ -8,11 +8,13 @@ // License: geo_mechanics_application/license.txt // // Main authors: Wijtze Pieter Kikstra +// Gennady Markelov // #include "custom_utilities/math_utilities.h" #include "custom_utilities/stress_strain_utilities.h" #include "testing/testing.h" +#include "utilities/math_utils.h" #include using namespace Kratos; @@ -117,4 +119,75 @@ KRATOS_TEST_CASE_IN_SUITE(CheckCalculateMohrCoulombPressureCapacityShearOnly, Kr 1.E-10); } +KRATOS_TEST_CASE_IN_SUITE(CheckCalculateCauchyStrain, KratosGeoMechanicsFastSuite) +{ + Matrix B(5, 5); + // clang-format off + B <<=1.0, 2.0, 3.0, 4.0, 5.0, + 1.1, 1.2, 1.3, 1.4, 1.5, + 1.0, 0.9, 0.8, 0.7, 0.6, + 0.0, 1.0, 2.0, 3.0, 4.0, + 5.0, 4.0, 3.0, 2.0, 1.0; + // clang-format on + + Vector displacements(5); + displacements <<= 0.01, 0.02, 0.03, 0.04, 0.05; + + const auto strain = StressStrainUtilities::CalculateCauchyStrain(B, displacements); + + Vector expected_strain(5); + expected_strain <<= 0.55, 0.205, 0.11, 0.4, 0.35; + + KRATOS_EXPECT_VECTOR_NEAR(strain, expected_strain, 1.E-10) +} + +KRATOS_TEST_CASE_IN_SUITE(CheckCalculateStrains, KratosGeoMechanicsFastSuite) +{ + Matrix B(4, 4); + // clang-format off + B <<=1.0, 2.0, 3.0, 4.0, + 1.1, 1.2, 1.3, 1.4, + 1.0, 0.9, 0.8, 0.7, + 0.0, 1.0, 2.0, 3.0; + // clang-format on + + Vector displacements(4); + displacements <<= 0.01, 0.02, 0.03, 0.04; + + bool use_hencky_strain = false; + std::size_t voigt_size = 4; + + std::vector Bs; + Bs.push_back(B); + Bs.push_back(B); + + std::vector deformation_gradients; + Matrix deformation_gradient = std::sqrt(3.) * IdentityMatrix(3); + deformation_gradients.push_back(deformation_gradient); + deformation_gradients.push_back(deformation_gradient); + + auto strains = StressStrainUtilities::CalculateStrains(deformation_gradients, Bs, displacements, + use_hencky_strain, voigt_size); + Vector expected_strain(4); + expected_strain <<= 0.3, 0.13, 0.08, 0.2; + std::vector expected_strains; + expected_strains.push_back(expected_strain); + expected_strains.push_back(expected_strain); + + for (size_t i = 0; i < strains.size(); ++i) + KRATOS_EXPECT_VECTOR_NEAR(strains[i], expected_strains[i], 1.E-10) + + use_hencky_strain = true; + strains = StressStrainUtilities::CalculateStrains(deformation_gradients, Bs, displacements, + use_hencky_strain, voigt_size); + + expected_strain <<= 0.549306, 0.549306, 0.549306, 0; + expected_strains.clear(); + expected_strains.push_back(expected_strain); + expected_strains.push_back(expected_strain); + + for (size_t i = 0; i < strains.size(); ++i) + KRATOS_EXPECT_VECTOR_NEAR(strains[i], expected_strains[i], 1.E-6) +} + } // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_dispersion_law.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_dispersion_law.cpp index 357700305952..fc6516a1f782 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_dispersion_law.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_dispersion_law.cpp @@ -33,11 +33,9 @@ KRATOS_TEST_CASE_IN_SUITE(CalculateThermalDispersionMatrix2D, KratosGeoMechanics const SizeType dimension = 2; GeoThermalDispersionLaw geo_thermal_dispersion_2D_law(dimension); - ProcessInfo info; const Matrix thermal_dispersion_matrix = - geo_thermal_dispersion_2D_law.CalculateThermalDispersionMatrix( - *cond_prop, info); + geo_thermal_dispersion_2D_law.CalculateThermalDispersionMatrix(*cond_prop); Matrix expected_solution = ZeroMatrix(2, 2); expected_solution(0, 0) = 1125.0; @@ -74,11 +72,9 @@ KRATOS_TEST_CASE_IN_SUITE(CalculateThermalDispersionMatrix3D, KratosGeoMechanics const SizeType dimension = 3; GeoThermalDispersionLaw geo_thermal_dispersion_3D_law(dimension); - ProcessInfo info; const Matrix thermal_dispersion_matrix = - geo_thermal_dispersion_3D_law.CalculateThermalDispersionMatrix( - *cond_prop, info); + geo_thermal_dispersion_3D_law.CalculateThermalDispersionMatrix(*cond_prop); Matrix expected_solution = ZeroMatrix(3, 3); expected_solution(0, 0) = 800.0; @@ -101,12 +97,9 @@ KRATOS_TEST_CASE_IN_SUITE(CalculateThermalDispersionMatrix3D, KratosGeoMechanics } } -KRATOS_TEST_CASE_IN_SUITE(GetWorkingSpaceDimension_ReturnsCorrectValue, KratosGeoMechanicsFastSuite) +KRATOS_TEST_CASE_IN_SUITE(TestDispersionLawThrowsWhenDimensionInvalid, KratosGeoMechanicsFastSuite) { - constexpr SizeType dimension = 3; - GeoThermalDispersionLaw geo_thermal_dispersion_3D_law(dimension); - - KRATOS_EXPECT_EQ(geo_thermal_dispersion_3D_law.WorkingSpaceDimension(), dimension); + KRATOS_EXPECT_EXCEPTION_IS_THROWN(GeoThermalDispersionLaw law{0}, "Got invalid number of dimensions: 0") } } // namespace Kratos::Testing diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_filter_law.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_filter_law.cpp new file mode 100644 index 000000000000..1d745b3804e8 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_thermal_filter_law.cpp @@ -0,0 +1,40 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Mohamed Nabi +// + +#include "custom_constitutive/thermal_filter_law.h" +#include "geo_mechanics_application.h" +#include "includes/ublas_interface.h" +#include "testing/testing.h" + +namespace Kratos::Testing +{ + +KRATOS_TEST_CASE_IN_SUITE(CalculateThermalFilterLawMatrix, KratosGeoMechanicsFastSuite) +{ + Model current_model; + auto& r_model_part = current_model.CreateModelPart("ModelPart"); + + auto p_cond_prop = r_model_part.CreateNewProperties(0); + p_cond_prop->SetValue(THERMAL_CONDUCTIVITY_WATER, 1000.0); + + GeoThermalFilterLaw geo_thermal_filter_law; + + const Matrix thermal_filter_matrix = geo_thermal_filter_law.CalculateThermalDispersionMatrix(*p_cond_prop); + + Matrix expected_solution = ScalarMatrix(1, 1, 1000.0); + + constexpr double tolerance{1.0e-6}; + + KRATOS_EXPECT_MATRIX_NEAR(thermal_filter_matrix, expected_solution, tolerance) +} + +} // namespace Kratos::Testing diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_three_dimensional_stress_state.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_three_dimensional_stress_state.cpp index ddc425d8c2e9..958c3a3b1203 100644 --- a/applications/GeoMechanicsApplication/tests/cpp_tests/test_three_dimensional_stress_state.cpp +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_three_dimensional_stress_state.cpp @@ -112,4 +112,29 @@ KRATOS_TEST_CASE_IN_SUITE(ThreeDimensionalStressState_CalculateGreenLagrangeStra KRATOS_CHECK_VECTOR_NEAR(expected_vector, calculated_vector, 1e-12) } +KRATOS_TEST_CASE_IN_SUITE(ThreeDimensionalStressState_GivesCorrectVoigtVector, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + Vector voigt_vector = p_stress_state_policy->GetVoigtVector(); + + Vector expected_voigt_vector(6); + expected_voigt_vector <<= 1.0, 1.0, 1.0, 0.0, 0.0, 0.0; + KRATOS_EXPECT_VECTOR_NEAR(voigt_vector, expected_voigt_vector, 1.E-10) +} + +KRATOS_TEST_CASE_IN_SUITE(ThreeDimensionalStressState_GivesCorrectVoigtSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetVoigtSize(), VOIGT_SIZE_3D); +} + +KRATOS_TEST_CASE_IN_SUITE(ThreeDimensionalStressState_GivesCorrectStressTensorSize, KratosGeoMechanicsFastSuite) +{ + const std::unique_ptr p_stress_state_policy = + std::make_unique(); + KRATOS_EXPECT_EQ(p_stress_state_policy->GetStressTensorSize(), STRESS_TENSOR_SIZE_3D); +} + } // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/cpp_tests/test_transport_equation_utilities.cpp b/applications/GeoMechanicsApplication/tests/cpp_tests/test_transport_equation_utilities.cpp new file mode 100644 index 000000000000..e5e0fc372e9e --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/cpp_tests/test_transport_equation_utilities.cpp @@ -0,0 +1,207 @@ +// KRATOS___ +// // ) ) +// // ___ ___ +// // ____ //___) ) // ) ) +// // / / // // / / +// ((____/ / ((____ ((___/ / MECHANICS +// +// License: geo_mechanics_application/license.txt +// +// Main authors: Richard Faasse +// + +#include "custom_utilities/transport_equation_utilities.hpp" +#include "testing/testing.h" +#include + +namespace +{ + +constexpr auto tolerance = 1.0e-12; + +} + +namespace Kratos::Testing +{ + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotModulusInverse_GivesExpectedResult, KratosGeoMechanicsFastSuite) +{ + Properties properties; + properties[IGNORE_UNDRAINED] = false; + properties[POROSITY] = 0.5; + properties[BULK_MODULUS_SOLID] = 1.0e9; + properties[BULK_MODULUS_FLUID] = 2.0e6; + const double biot_coefficient = 1.0; + const double degree_of_saturation = 0.3; + const double derivative_of_saturation = 0.2; + + const double expected_value = -0.09999992485; + KRATOS_EXPECT_DOUBLE_EQ(GeoTransportEquationUtilities::CalculateBiotModulusInverse( + biot_coefficient, degree_of_saturation, derivative_of_saturation, properties), + expected_value); +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotModulusInverse_ReturnsLargeNumber_WhenIgnoreUndrained, KratosGeoMechanicsFastSuite) +{ + Properties properties; + properties[IGNORE_UNDRAINED] = true; + properties[POROSITY] = 0.5; + properties[BULK_MODULUS_SOLID] = 1.0e9; + properties[BULK_MODULUS_FLUID] = 2.0e6; + const double biot_coefficient = 1.0; + const double degree_of_saturation = 0.3; + const double derivative_of_saturation = 0.2; + + const auto large_number = 1e10; + KRATOS_EXPECT_GT(GeoTransportEquationUtilities::CalculateBiotModulusInverse( + biot_coefficient, degree_of_saturation, derivative_of_saturation, properties), + large_number); +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotModulusInverse_DoesNotThrow_ForEmptyProperties, KratosGeoMechanicsFastSuite) +{ + const Properties properties; + const double biot_coefficient = 1.0; + const double degree_of_saturation = 0.3; + const double derivative_of_saturation = 0.2; + + KRATOS_EXPECT_TRUE(std::isnan(GeoTransportEquationUtilities::CalculateBiotModulusInverse( + biot_coefficient, degree_of_saturation, derivative_of_saturation, properties))) +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBulkModulus_ReturnsZeroForZeroConstitutiveMatrix, KratosGeoMechanicsFastSuite) +{ + ZeroMatrix constitutive_matrix(3, 3); + KRATOS_EXPECT_DOUBLE_EQ(GeoTransportEquationUtilities::CalculateBulkModulus(constitutive_matrix), 0.0); +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBulkModulus_Throws_WhenConstitutiveMatrixIsEmpty, KratosGeoMechanicsFastSuite) +{ + const Matrix constitutive_matrix; + KRATOS_EXPECT_EXCEPTION_IS_THROWN( + [[maybe_unused]] const auto bulk_modulus = + GeoTransportEquationUtilities::CalculateBulkModulus(constitutive_matrix), + "Constitutive matrix is empty, aborting bulk modulus calculation.") +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBulkModulus_GivesExpectedResult_ForFilledConstitutiveMatrix, KratosGeoMechanicsFastSuite) +{ + Matrix constitutive_matrix(3, 3); + constitutive_matrix <<= 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0; + + KRATOS_EXPECT_DOUBLE_EQ(GeoTransportEquationUtilities::CalculateBulkModulus(constitutive_matrix), -11.0); +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotCoefficients_GivesExpectedResults_WhenPropertyHasBiotCoefficient, + KratosGeoMechanicsFastSuite) +{ + const std::vector constitutive_matrices(2, ZeroMatrix(3, 3)); + + const double biot_coefficient = 1.2; + Properties properties; + properties[BIOT_COEFFICIENT] = biot_coefficient; + + const auto actual_values = + GeoTransportEquationUtilities::CalculateBiotCoefficients(constitutive_matrices, properties); + + const std::vector expected_values(2, biot_coefficient); + KRATOS_CHECK_VECTOR_NEAR(expected_values, actual_values, 1e-12) +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotCoefficients_GivesExpectedResults, KratosGeoMechanicsFastSuite) +{ + std::vector constitutive_matrices; + constitutive_matrices.emplace_back(ScalarMatrix(3, 3, 1.0)); + constitutive_matrices.emplace_back(ScalarMatrix(3, 3, 3.0)); + + Properties properties; + properties[BULK_MODULUS_SOLID] = 1.0; + + const auto actual_values = + GeoTransportEquationUtilities::CalculateBiotCoefficients(constitutive_matrices, properties); + + const std::vector expected_values = {4.0 / 3.0, 2.0}; + KRATOS_CHECK_VECTOR_NEAR(expected_values, actual_values, 1e-12) +} + +KRATOS_TEST_CASE_IN_SUITE(CalculateBiotCoefficients_GivesInfResults_ForZeroBulkModulus, KratosGeoMechanicsFastSuite) +{ + std::vector constitutive_matrices; + constitutive_matrices.emplace_back(ScalarMatrix(3, 3, 1.0)); + constitutive_matrices.emplace_back(ScalarMatrix(3, 3, 3.0)); + + Properties properties; + properties[BULK_MODULUS_SOLID] = 0.0; + + const auto actual_values = + GeoTransportEquationUtilities::CalculateBiotCoefficients(constitutive_matrices, Properties()); + + // Due to a division by zero, we end up with inf + KRATOS_EXPECT_TRUE(std::all_of(actual_values.begin(), actual_values.end(), + [](const double value) { return std::isinf(value); })) +} + +KRATOS_TEST_CASE_IN_SUITE(EachFluidPressureIsTheInnerProductOfShapeFunctionsAndPressure, KratosGeoMechanicsFastSuite) +{ + auto shape_function_values = Matrix{3, 3, 0.0}; + // clang-format off + shape_function_values <<= 0.8, 0.2, 0.3, + 0.1, 0.7, 0.4, + 0.2, 0.5, 0.6; + // clang-format on + + auto pore_water_pressures = Vector(3); + pore_water_pressures <<= 2.0, 3.0, 4.0; + + const auto expected_fluid_pressures = std::vector{3.4, 3.9, 4.3}; + KRATOS_EXPECT_VECTOR_NEAR(GeoTransportEquationUtilities::CalculateFluidPressures( + shape_function_values, pore_water_pressures), + expected_fluid_pressures, tolerance) +} + +KRATOS_TEST_CASE_IN_SUITE(PermeabilityUpdateFactorEqualsOneWhenChangeInverseFactorIsNotGiven, KratosGeoMechanicsFastSuite) +{ + const auto unused_strain_vectors = std::vector(3, Vector{}); + auto properties = Properties{}; + + const auto expected_factors = std::vector(unused_strain_vectors.size(), 1.0); + KRATOS_EXPECT_VECTOR_NEAR(GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + unused_strain_vectors, properties), + expected_factors, tolerance) +} + +KRATOS_TEST_CASE_IN_SUITE(PermeabilityUpdateFactorEqualsOneWhenChangeInverseFactorIsNonPositive, KratosGeoMechanicsFastSuite) +{ + const auto unused_strain_vectors = std::vector(3, Vector{}); + auto properties = Properties{}; + properties[PERMEABILITY_CHANGE_INVERSE_FACTOR] = -1.0; + + const auto expected_factors = std::vector(unused_strain_vectors.size(), 1.0); + KRATOS_EXPECT_VECTOR_NEAR(GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + unused_strain_vectors, properties), + expected_factors, tolerance) + + properties[PERMEABILITY_CHANGE_INVERSE_FACTOR] = 0.0; + + KRATOS_EXPECT_VECTOR_NEAR(GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + unused_strain_vectors, properties), + expected_factors, tolerance) +} + +KRATOS_TEST_CASE_IN_SUITE(PermeabilityUpdateFactorIsComputedFromStrainsAndPropertiesWhenChangeInverseFactorIsPositive, KratosGeoMechanicsFastSuite) +{ + auto test_strains = Vector{3}; + test_strains <<= 0.001, 0.002, 0.0; + auto strain_vectors = std::vector{test_strains, 2.0 * test_strains, 4.0 * test_strains}; + + auto properties = Properties{}; + properties[PERMEABILITY_CHANGE_INVERSE_FACTOR] = 0.5; + properties[POROSITY] = 0.2; + + const auto expected_factors = std::vector{1.00433, 1.0087, 1.01753}; + KRATOS_EXPECT_VECTOR_NEAR(GeoTransportEquationUtilities::CalculatePermeabilityUpdateFactors( + strain_vectors, properties), + expected_factors, 1e-5) +} + +} // namespace Kratos::Testing \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_GeoMechanicsApplication.py b/applications/GeoMechanicsApplication/tests/test_GeoMechanicsApplication.py index eeaa0a9a2a52..a9701e86ca97 100644 --- a/applications/GeoMechanicsApplication/tests/test_GeoMechanicsApplication.py +++ b/applications/GeoMechanicsApplication/tests/test_GeoMechanicsApplication.py @@ -47,6 +47,7 @@ from test_dirichlet_u import KratosGeoMechanicsDirichletUTests from test_normal_load_on_hexa_element import KratosGeoMechanicsNormalLoadHexaTests from test_pressure_line_element import KratosGeoMechanicsTransientPressureLineElementTests +from test_pressure_point_flux import KratosGeoMechanicsTransientPressurePointFluxTests from settlement_workflow import KratosGeoMechanicsSettlementWorkflow def AssembleTestSuites(): @@ -108,6 +109,7 @@ def AssembleTestSuites(): KratosGeoMechanicsTransientThermalTests, KratosGeoMechanicsTimeIntegrationTests, KratosGeoMechanicsTransientPressureLineElementTests, + KratosGeoMechanicsTransientPressurePointFluxTests, KratosGeoMechanicsSettlementWorkflow ] night_test_cases.extend(small_test_cases) diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux.py b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux.py new file mode 100644 index 000000000000..ec6f4e8233d4 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux.py @@ -0,0 +1,33 @@ +import os + +import KratosMultiphysics.KratosUnittest as KratosUnittest +import test_helper + +class KratosGeoMechanicsTransientPressurePointFluxTests(KratosUnittest.TestCase): + """ + This class contains benchmark tests which are checked with the regression on a previously obtained value. + """ + etalon_value1 = -21000.0 + + def setUp(self): + # Code here will be placed BEFORE every test in this TestCase. + pass + + def tearDown(self): + # Code here will be placed AFTER every test in this TestCase. + pass + + def check_water_pressure(self, test_name, etalon_value): + file_path = test_helper.get_file_path(os.path.join('test_pressure_point_flux', test_name)) + simulation = test_helper.run_kratos(file_path) + pressure = test_helper.get_water_pressure(simulation) + self.assertAlmostEqual(etalon_value, pressure[2]) + + def test_pressure_point_flux_line_element2D2N(self): + self.check_water_pressure("test_pressure_point_flux_line_element2D2N", self.etalon_value1) + + def test_pressure_point_flux_line_element3D2N(self): + self.check_water_pressure("test_pressure_point_flux_line_element3D2N", self.etalon_value1) + +if __name__ == '__main__': + KratosUnittest.main() diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters2D.json b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters2D.json new file mode 100644 index 000000000000..cddec84735fd --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters2D.json @@ -0,0 +1,29 @@ +{ + "properties": [{ + "model_part_name" : "PorousDomain.filter", + "properties_id" : 1, + "Material" : { + "constitutive_law" : { + "name" : "GeoLinearElasticPlaneStrain2DLaw" + }, + "Variables" : { + "IGNORE_UNDRAINED" : false, + "YOUNG_MODULUS" : 1.000000e+07, + "POISSON_RATIO" : 0.000000e+00, + "DENSITY_SOLID" : 2.650000e+03, + "DENSITY_WATER" : 1.000000e+03, + "POROSITY" : 1.000000e-01, + "BULK_MODULUS_SOLID" : 9.000000e+19, + "BULK_MODULUS_FLUID" : 1.000000e+20, + "PERMEABILITY_XX" : 2.000000e-04, + "DYNAMIC_VISCOSITY" : 1.000000e-03, + "BIOT_COEFFICIENT" : 1.000000e+00, + "RETENTION_LAW" : "SaturatedLaw", + "RESIDUAL_SATURATION" : 0.000000e+00, + "CROSS_AREA" : 1.0 + }, + "Tables": { + } + } + }] +} diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters3D.json b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters3D.json new file mode 100644 index 000000000000..c6ec70a48a08 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/Common/MaterialParameters3D.json @@ -0,0 +1,29 @@ +{ + "properties": [{ + "model_part_name" : "PorousDomain.filter", + "properties_id" : 1, + "Material" : { + "constitutive_law" : { + "name" : "LinearElasticK03DLaw" + }, + "Variables" : { + "IGNORE_UNDRAINED" : false, + "YOUNG_MODULUS" : 1.000000e+07, + "POISSON_RATIO" : 0.000000e+00, + "DENSITY_SOLID" : 2.650000e+03, + "DENSITY_WATER" : 1.000000e+03, + "POROSITY" : 1.000000e-01, + "BULK_MODULUS_SOLID" : 9.000000e+19, + "BULK_MODULUS_FLUID" : 1.000000e+20, + "PERMEABILITY_XX" : 2.000000e-04, + "DYNAMIC_VISCOSITY" : 1.000000e-03, + "BIOT_COEFFICIENT" : 1.000000e+00, + "RETENTION_LAW" : "SaturatedLaw", + "SATURATED_SATURATION" : 1.000000e+00, + "CROSS_AREA" : 1.0 + }, + "Tables": { + } + } + }] +} diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/README.md b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/README.md new file mode 100644 index 000000000000..98503305a2e9 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/README.md @@ -0,0 +1,24 @@ +# Test Cases for Water Pore Pressure Point Flux + +**Author:** [Mohamed Nabi](https://github.com/mnabideltares) + +**Source files:** [Water pore pressure point flux](https://github.com/KratosMultiphysics/Kratos/tree/master/applications/GeoMechanicsApplication/tests/test_pressure_point_flux) + +## Case Specification +In this water-pressure test case, a 3 [m] deep soil is considered, with everywhere set to 10 $\mathrm{[Pa]}$ as initial condition. Then the top boundary is set to 0 $\mathrm{[Pa]}$ and a water flux of 100 $\mathrm{[m^3/s]}$ is imposed at the bottom boundary. The simulation spans 50 hours to allow for a transition from the intial condition to a linear pressure profile along the depth. This test is conducted for two configurations, including 2D2N and 3D2N line elements. The pressure distribution along the depth is then evaluated with its steady state analytical results. + +The boundary conditions are shown below: + +Visualization of the Boundary conditions + +## Results + +The picture below illustrates the pressure profile resulting from the simulation (as an example the 2D2N test is shown below). + +Pressure along depth at the last time step + +These results are associated with the final time step after the solution reaches a steady state. The results for both test configurations are identical. The analytical solution is: + +$P = 10500 y$ + +In this test case, the result at node number 3 at location $y = -2 \mathrm{[m]}$ is compared with the analytical solution. The value of the pressure at node 3 is -21000 $\mathrm{[Pa]}$ \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element.svg b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element.svg new file mode 100644 index 000000000000..3f9b0fe501f0 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element.svg @@ -0,0 +1 @@ +Pressure=0PaWater flux = 100 m3/s \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element_2d2n_result.svg b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element_2d2n_result.svg new file mode 100644 index 000000000000..187d898433e7 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/documentation_data/test_pressure_point_flux_line_element_2d2n_result.svg @@ -0,0 +1 @@ +-3-2.5-2-1.5-1-0.50-35000-30000-25000-20000-15000-10000-50000Depth [m]Water Pressure [Pa] \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/ProjectParameters.json new file mode 100644 index 000000000000..071acdecabb8 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/ProjectParameters.json @@ -0,0 +1,154 @@ +{ + "problem_data": { + "problem_name" : "test_pressure_point_flux_line_element2D2N", + "start_time" : 0.000000e+00, + "end_time" : 1.800000e+05, + "echo_level" : 0, + "parallel_type" : "OpenMP", + "number_of_threads" : 1 + }, + "solver_settings" : { + "solver_type" : "Pw", + "model_part_name" : "PorousDomain", + "domain_size" : 2, + "model_import_settings" : { + "input_type" : "mdpa", + "input_filename" : "test_pressure_point_flux_line_element2D2N" + }, + "material_import_settings" : { + "materials_filename" : "../Common/MaterialParameters2D.json" + }, + "time_stepping" : { + "time_step" : 3.600, + "max_delta_time_factor" : 1000 + }, + "buffer_size" : 2, + "echo_level" : 0, + "clear_storage" : false, + "compute_reactions" : false, + "move_mesh_flag" : false, + "reform_dofs_at_each_step" : false, + "nodal_smoothing" : false, + "block_builder" : true, + "solution_type" : "Transient_Groundwater_Flow", + "scheme_type" : "Backward_Euler", + "reset_displacements" : false, + "newmark_beta" : 0.25, + "newmark_gamma" : 0.5, + "newmark_theta" : 0.5, + "rayleigh_m" : 0.0, + "rayleigh_k" : 0.0, + "strategy_type" : "newton_raphson", + "convergence_criterion" : "water_pressure_criterion", + "displacement_relative_tolerance" : 1.0E-4, + "displacement_absolute_tolerance" : 1.0E-9, + "residual_relative_tolerance" : 1.0E-4, + "residual_absolute_tolerance" : 1.0E-9, + "water_pressure_relative_tolerance" : 1.0E-4, + "water_pressure_absolute_tolerance" : 1.0E-9, + "min_iterations" : 2, + "max_iterations" : 15, + "number_cycles" : 2, + "reduction_factor" : 0.5, + "increase_factor" : 2.0, + "desired_iterations" : 2, + "max_radius_factor" : 10.0, + "min_radius_factor" : 0.1, + "calculate_reactions" : true, + "max_line_search_iterations" : 5, + "first_alpha_value" : 0.5, + "second_alpha_value" : 1.0, + "min_alpha" : 0.1, + "max_alpha" : 2.0, + "line_search_tolerance" : 0.5, + "rotation_dofs" : true, + "linear_solver_settings" : { + "solver_type" : "LinearSolversApplication.sparse_lu", + "scaling" : true + }, + "problem_domain_sub_model_part_list" : ["filter"], + "processes_sub_model_part_list" : ["Start","Gravity","top","bottom"], + "body_domain_sub_model_part_list" : ["filter"] + }, + "output_processes" : { + "gid_output" : [{ + "python_module" : "gid_output_process", + "kratos_module" : "KratosMultiphysics", + "process_name" : "GiDOutputProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.filter", + "output_name" : "test_pressure_point_flux_line_element2D2N", + "postprocess_parameters" : { + "result_file_configuration": { + "gidpost_flags" : { + "WriteDeformedMeshFlag" : "WriteUndeformed", + "WriteConditionsFlag" : "WriteElementsOnly", + "GiDPostMode" : "GiD_PostAscii", + "MultiFileFlag" : "SingleFile" + }, + "file_label" : "step", + "output_control_type" : "step", + "output_interval" : 1, + "body_output" : true, + "node_output" : false, + "skin_output" : false, + "plane_output" : [], + "nodal_results" : ["WATER_PRESSURE"], + "gauss_point_results" : [] + }, + "point_data_configuration" : [] + } + } + }] + }, + "processes": { + "constraints_process_list" : [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.Start", + "variable_name" : "WATER_PRESSURE", + "is_fixed" : false, + "fluid_pressure_type" : "Uniform", + "value" : 10.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.top", + "variable_name" : "WATER_PRESSURE", + "is_fixed" : true, + "fluid_pressure_type" : "Uniform", + "value" : 0.0, + "table" : 0 + } + }], + "loads_process_list" : [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.bottom", + "variable_name" : "NORMAL_FLUID_FLUX", + "value" : 100, + "table" : 0 + } + },{ + "python_module" : "apply_vector_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyVectorConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.Gravity", + "variable_name" : "VOLUME_ACCELERATION", + "active" : [false, true, false], + "value" : [0.0, -10.0, 0.0], + "table" : [0, 0, 0] + } + }], + "auxiliar_process_list" : [] + } +} diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/test_pressure_point_flux_line_element2D2N.mdpa b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/test_pressure_point_flux_line_element2D2N.mdpa new file mode 100644 index 000000000000..47bc8af0da2d --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element2D2N/test_pressure_point_flux_line_element2D2N.mdpa @@ -0,0 +1,106 @@ +Begin Properties 1 +End Properties + + +Begin Nodes + 1 0.000000e+00 0.000000e+00 0.000000e+00 + 2 0.000000e+00 -1.000000e+00 0.000000e+00 + 3 0.000000e+00 -2.000000e+00 0.000000e+00 + 4 0.000000e+00 -3.000000e+00 0.000000e+00 +End Nodes + + +Begin Elements TransientPwLineElement2D2N + 1 1 1 2 + 2 1 2 3 + 3 1 3 4 +End Elements + + +Begin Conditions PwPointFluxCondition2D1N + 1 1 4 +End Conditions + + +Begin SubModelPart Start + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart filter + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions + End SubModelPart + + +Begin SubModelPart top + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart bottom + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 4 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 1 + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart Gravity + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/ProjectParameters.json new file mode 100644 index 000000000000..83fc8f779d5e --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/ProjectParameters.json @@ -0,0 +1,154 @@ +{ + "problem_data": { + "problem_name" : "test_pressure_point_flux_line_element3D2N", + "start_time" : 0.000000e+00, + "end_time" : 1.800000e+05, + "echo_level" : 0, + "parallel_type" : "OpenMP", + "number_of_threads" : 1 + }, + "solver_settings" : { + "solver_type" : "Pw", + "model_part_name" : "PorousDomain", + "domain_size" : 3, + "model_import_settings" : { + "input_type" : "mdpa", + "input_filename" : "test_pressure_point_flux_line_element3D2N" + }, + "material_import_settings" : { + "materials_filename" : "../Common/MaterialParameters3D.json" + }, + "time_stepping" : { + "time_step" : 3.600, + "max_delta_time_factor" : 1000 + }, + "buffer_size" : 2, + "echo_level" : 0, + "clear_storage" : false, + "compute_reactions" : false, + "move_mesh_flag" : false, + "reform_dofs_at_each_step" : false, + "nodal_smoothing" : false, + "block_builder" : true, + "solution_type" : "Transient_Groundwater_Flow", + "scheme_type" : "Backward_Euler", + "reset_displacements" : false, + "newmark_beta" : 0.25, + "newmark_gamma" : 0.5, + "newmark_theta" : 0.5, + "rayleigh_m" : 0.0, + "rayleigh_k" : 0.0, + "strategy_type" : "newton_raphson", + "convergence_criterion" : "water_pressure_criterion", + "displacement_relative_tolerance" : 1.0E-4, + "displacement_absolute_tolerance" : 1.0E-9, + "residual_relative_tolerance" : 1.0E-4, + "residual_absolute_tolerance" : 1.0E-9, + "water_pressure_relative_tolerance" : 1.0E-4, + "water_pressure_absolute_tolerance" : 1.0E-9, + "min_iterations" : 2, + "max_iterations" : 15, + "number_cycles" : 2, + "reduction_factor" : 0.5, + "increase_factor" : 2.0, + "desired_iterations" : 2, + "max_radius_factor" : 10.0, + "min_radius_factor" : 0.1, + "calculate_reactions" : true, + "max_line_search_iterations" : 5, + "first_alpha_value" : 0.5, + "second_alpha_value" : 1.0, + "min_alpha" : 0.1, + "max_alpha" : 2.0, + "line_search_tolerance" : 0.5, + "rotation_dofs" : true, + "linear_solver_settings" : { + "solver_type" : "LinearSolversApplication.sparse_lu", + "scaling" : true + }, + "problem_domain_sub_model_part_list" : ["filter"], + "processes_sub_model_part_list" : ["Start","Gravity","top","bottom"], + "body_domain_sub_model_part_list" : ["filter"] + }, + "output_processes" : { + "gid_output" : [{ + "python_module" : "gid_output_process", + "kratos_module" : "KratosMultiphysics", + "process_name" : "GiDOutputProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.filter", + "output_name" : "test_pressure_point_flux_line_element3D2N", + "postprocess_parameters" : { + "result_file_configuration": { + "gidpost_flags" : { + "WriteDeformedMeshFlag" : "WriteUndeformed", + "WriteConditionsFlag" : "WriteElementsOnly", + "GiDPostMode" : "GiD_PostAscii", + "MultiFileFlag" : "SingleFile" + }, + "file_label" : "step", + "output_control_type" : "step", + "output_interval" : 1, + "body_output" : true, + "node_output" : false, + "skin_output" : false, + "plane_output" : [], + "nodal_results" : ["WATER_PRESSURE"], + "gauss_point_results" : [] + }, + "point_data_configuration" : [] + } + } + }] + }, + "processes": { + "constraints_process_list" : [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.Start", + "variable_name" : "WATER_PRESSURE", + "is_fixed" : false, + "fluid_pressure_type" : "Uniform", + "value" : 10.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.top", + "variable_name" : "WATER_PRESSURE", + "is_fixed" : true, + "fluid_pressure_type" : "Uniform", + "value" : 0.0, + "table" : 0 + } + }], + "loads_process_list" : [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.bottom", + "variable_name" : "NORMAL_FLUID_FLUX", + "value" : 100, + "table" : 0 + } + },{ + "python_module" : "apply_vector_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyVectorConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.Gravity", + "variable_name" : "VOLUME_ACCELERATION", + "active" : [false, true, false], + "value" : [0.0, -10.0, 0.0], + "table" : [0, 0, 0] + } + }], + "auxiliar_process_list" : [] + } +} diff --git a/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/test_pressure_point_flux_line_element3D2N.mdpa b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/test_pressure_point_flux_line_element3D2N.mdpa new file mode 100644 index 000000000000..26e2fe8e30a7 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_pressure_point_flux/test_pressure_point_flux_line_element3D2N/test_pressure_point_flux_line_element3D2N.mdpa @@ -0,0 +1,106 @@ +Begin Properties 1 +End Properties + + +Begin Nodes + 1 0.000000e+00 0.000000e+00 0.000000e+00 + 2 0.000000e+00 -1.000000e+00 0.000000e+00 + 3 0.000000e+00 -2.000000e+00 0.000000e+00 + 4 0.000000e+00 -3.000000e+00 0.000000e+00 +End Nodes + + +Begin Elements TransientPwLineElement3D2N + 1 1 1 2 + 2 1 2 3 + 3 1 3 4 +End Elements + + +Begin Conditions PwPointFluxCondition3D1N + 1 1 4 +End Conditions + + +Begin SubModelPart Start + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart filter + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions + End SubModelPart + + +Begin SubModelPart top + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart bottom + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 4 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 1 + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart Gravity + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element.svg b/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element.svg new file mode 100644 index 000000000000..90f9fb845eb1 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element.svg @@ -0,0 +1 @@ +0°C0°CFlux = 100 W/m2Flux = 100 W/m2Filter \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element_2D3N_result.svg b/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element_2D3N_result.svg new file mode 100644 index 000000000000..67f52b891c05 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/documentation_data/test_thermal_filter_element_2D3N_result.svg @@ -0,0 +1,4645 @@ + + +UNNAMED + +Creator: GiD 16.1.8d + GL2PS 1.3.8, (C) 1999-2012 C. Geuzaine +For: GiD-gl2ps +CreationDate: Mon May 13 16:24:34 2024 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +y +x + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +z + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0 + +5.5596 +step 8640000 +11.119 +Contour Fill of TEMPERATURE. +16.679 + +22.238 + +27.798 + +33.357 + +38.917 + +44.476 +50.036 + +TEMPERATURE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +GiD + + + + + + + + + + + + + + diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_1/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_1/MaterialParameters.json index 971f9426004f..c2602bea1b76 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_1/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_1/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.0, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_2/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_2/MaterialParameters.json index 470dd99ba134..4b197e24fc6d 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_2/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_2/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_3/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_3/MaterialParameters.json index 9f459251a905..114a9db905df 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_3/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_3/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_4/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_4/MaterialParameters.json index 1a125db227f3..4f70892b9fe0 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_4/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_4/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_5/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_5/MaterialParameters.json index ca3d1d3f5453..19ec024b4031 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_5/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_5/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_6/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_6/MaterialParameters.json index 49682418578e..3d5dcd81daca 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_6/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_6/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_7/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_7/MaterialParameters.json index 11482da0f23e..c1d467d8a41b 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_7/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_7/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_8/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_8/MaterialParameters.json index 5bd0bcbac106..cdddc80d6b8e 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_8/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_micro_climate_8/MaterialParameters.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.Soil1", "properties_id" : 1, "Material" : { - "constitutive_law" : { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 1.700000e+03, "DENSITY_WATER" : 1000.0, "POROSITY" : 0.000000e+00, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/Common/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/Common/MaterialParameters.json new file mode 100644 index 000000000000..9eecf1e4cacc --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/Common/MaterialParameters.json @@ -0,0 +1,44 @@ +{ + "properties": [{ + "model_part_name" : "PorousDomain.soil", + "properties_id" : 1, + "Material" : { + "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", + "DENSITY_SOLID" : 2650.0, + "DENSITY_WATER" : 1000.0, + "POROSITY" : 0.3, + "RETENTION_LAW" : "SaturatedLaw", + "SATURATED_SATURATION" : 1.0, + "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, + "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, + "THERMAL_CONDUCTIVITY_SOLID_XX" : 2.65, + "THERMAL_CONDUCTIVITY_SOLID_YY" : 2.65, + "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, + "THERMAL_CONDUCTIVITY_WATER" : 0.48, + "SOLID_COMPRESSIBILITY" : 1.0, + "DYNAMIC_VISCOSITY" : 0.001 + }, + "Tables": {} + } + },{ + "model_part_name" : "PorousDomain.filter", + "properties_id" : 2, + "Material" : { + "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalFilterLaw", + "DENSITY_SOLID" : 2650.0, + "DENSITY_WATER" : 1000.0, + "POROSITY" : 1.0, + "RETENTION_LAW" : "SaturatedLaw", + "SATURATED_SATURATION" : 1.0, + "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, + "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, + "THERMAL_CONDUCTIVITY_SOLID_XX" : 2.65, + "THERMAL_CONDUCTIVITY_WATER" : 4800, + "CROSS_AREA" : 0.3 + }, + "Tables": {} + } + }] +} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/README.md b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/README.md new file mode 100644 index 000000000000..c04c9b38b95d --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/README.md @@ -0,0 +1,17 @@ +# Test Cases for Thermal Filter Element + +**Author:** [Mohamed Nabi](https://github.com/mnabideltares) + +**Source files:** [Thermal filter element with fixed temperature](https://github.com/KratosMultiphysics/Kratos/tree/master/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element) + +## Case Specification +In this thermal test case, a $2 \mathrm{[m]} \times 1 \mathrm{[m]}$ soil block is considered, with everywhere set to 0 $\mathrm{[^\circ C]}$. A well/filter passes vertically through middle of the domain. Heat fluxes are set at the top and bottom of the filter, with values of 100 $\mathrm{[W/m^2]}$. Dirichlet boundary conditions of temperature are set at the left and right of the soil domain, both with a value of 0 $\mathrm{[^\circ C]}$. The simulation spans 100 $\mathrm{[days]}$ to allow for a transition from the initial to a linear temperature profile. This test is conducted for various configurations, including 2D3N and 2D6N soil elements (with corresponding 2D2N and 2D3N filter elements). The temperature distribution is then evaluated with its own results. The boundary conditions are shown below: + +Visualization of the Boundary conditions + +## Results +The picture below illustrates the temperature contours resulting from the simulation (as an example the soil-element 2D6N test is shown below). + +Temperature profile at the last time step + +These results are associated with the final time step after the solution reaches a steady state. In this test case, the result at node number 80 is examined. The value of the temperature at node 80 is 34.657035390578656 $\mathrm{[^\circ C]}$. \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/ProjectParameters.json new file mode 100644 index 000000000000..c0d3ab3281bf --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/ProjectParameters.json @@ -0,0 +1,163 @@ +{ + "problem_data": { + "problem_name" : "test_thermal_filter_element_2D2N", + "start_time" : 0.0, + "end_time" : 8640000.0, + "echo_level" : 0, + "parallel_type" : "OpenMP", + "number_of_threads" : 1 + }, + "solver_settings": { + "solver_type" : "T", + "model_part_name" : "PorousDomain", + "domain_size" : 2, + "model_import_settings" : { + "input_type" : "mdpa", + "input_filename" : "test_thermal_filter_element_2D2N" + }, + "material_import_settings" : { + "materials_filename" : "../Common/MaterialParameters.json" + }, + "time_stepping" : { + "time_step" : 3600, + "max_delta_time_factor" : 1000 + }, + "buffer_size" : 2, + "echo_level" : 0, + "clear_storage" : false, + "compute_reactions" : false, + "move_mesh_flag" : false, + "reform_dofs_at_each_step" : false, + "nodal_smoothing" : false, + "block_builder" : true, + "solution_type" : "Transient_Heat_Transfer", + "scheme_type" : "Backward_Euler", + "reset_displacements" : false, + "newmark_beta" : 0.25, + "newmark_gamma" : 0.5, + "newmark_theta" : 0.5, + "rayleigh_m" : 0.0, + "rayleigh_k" : 0.0, + "strategy_type" : "newton_raphson", + "convergence_criterion" : "temperature_criterion", + "temperature_relative_tolerance" : 1.0E-4, + "temperature_absolute_tolerance" : 1.0E-9, + "residual_relative_tolerance" : 1.0E-4, + "residual_absolute_tolerance" : 1.0E-9, + "min_iterations" : 2, + "max_iterations" : 15, + "number_cycles" : 2, + "reduction_factor" : 0.5, + "increase_factor" : 2.0, + "desired_iterations" : 2, + "max_radius_factor" : 10.0, + "min_radius_factor" : 0.1, + "calculate_reactions" : true, + "max_line_search_iterations" : 5, + "first_alpha_value" : 0.5, + "second_alpha_value" : 1.0, + "min_alpha" : 0.1, + "max_alpha" : 2.0, + "line_search_tolerance" : 0.5, + "rotation_dofs" : true, + "linear_solver_settings" : { + "solver_type" : "bicgstab", + "tolerance" : 1.0e-6, + "max_iteration" : 1000, + "scaling" : true, + "preconditioner_type" : "ilu0" + }, + "problem_domain_sub_model_part_list" : ["filter","soil"], + "processes_sub_model_part_list" : ["initial","right","left","pipe_top","pipe_bottom"], + "body_domain_sub_model_part_list" : ["filter","soil"] + }, + "output_processes": { + "gid_output": [{ + "python_module" : "gid_output_process", + "kratos_module" : "KratosMultiphysics", + "process_name" : "GiDOutputProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.soil", + "output_name" : "test_thermal_filter_element_2D2N", + "postprocess_parameters" : { + "result_file_configuration" : { + "gidpost_flags" : { + "WriteDeformedMeshFlag" : "WriteUndeformed", + "WriteConditionsFlag" : "WriteElementsOnly", + "GiDPostMode" : "GiD_PostAscii", + "MultiFileFlag" : "SingleFile" + }, + "file_label" : "step", + "output_control_type" : "step", + "output_interval" : 1, + "body_output" : true, + "node_output" : false, + "skin_output" : false, + "plane_output" : [], + "nodal_results" : ["TEMPERATURE"], + "gauss_point_results" : [] + }, + "point_data_configuration" : [] + } + } + }] + }, + "processes": { + "constraints_process_list": [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.initial", + "variable_name" : "TEMPERATURE", + "is_fixed" : false, + "value" : 0.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.right", + "variable_name" : "TEMPERATURE", + "is_fixed" : true, + "value" : 0.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.left", + "variable_name" : "TEMPERATURE", + "is_fixed" : true, + "value" : 0.0, + "table" : 0 + } + }], + "loads_process_list": [{ + "python_module": "apply_scalar_constraint_table_process", + "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", + "process_name": "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name": "PorousDomain.pipe_top", + "variable_name": "NORMAL_HEAT_FLUX", + "value": 100.0, + "table": 0 + } + },{ + "python_module": "apply_scalar_constraint_table_process", + "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", + "process_name": "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name": "PorousDomain.pipe_bottom", + "variable_name": "NORMAL_HEAT_FLUX", + "value": 100.0, + "table": 0 + } + }], + "auxiliar_process_list": [] + } +} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/test_thermal_filter_element_2D2N.mdpa b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/test_thermal_filter_element_2D2N.mdpa new file mode 100644 index 000000000000..495a46bbbf19 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D2N/test_thermal_filter_element_2D2N.mdpa @@ -0,0 +1,642 @@ +Begin Properties 1 +End Properties + +Begin Properties 2 +End Properties + +Begin Nodes + 1 1.0000000000 0.0000000000 0.0000000000 + 2 0.8000000000 0.0000000000 0.0000000000 + 3 1.0000000000 0.2000000000 0.0000000000 + 4 0.8223290994 0.2833333333 0.0000000000 + 5 0.6535898385 0.2000000000 0.0000000000 + 6 0.6000000000 0.0000000000 0.0000000000 + 7 1.0000000000 0.4000000000 0.0000000000 + 8 0.6535898385 0.4000000000 0.0000000000 + 9 0.8267949192 0.5000000000 0.0000000000 + 10 0.4852292154 0.2431376160 0.0000000000 + 11 0.4000000000 0.0000000000 0.0000000000 + 12 1.0000000000 0.6000000000 0.0000000000 + 13 0.6535898385 0.6000000000 0.0000000000 + 14 0.4803847577 0.5000000000 0.0000000000 + 15 0.3018603958 0.2019633120 0.0000000000 + 16 0.8223290994 0.7166666667 0.0000000000 + 17 0.3071796770 0.4000000000 0.0000000000 + 18 0.2000000000 0.0000000000 0.0000000000 + 19 1.0000000000 0.8000000000 0.0000000000 + 20 0.6535898385 0.8000000000 0.0000000000 + 21 0.4669872981 0.7166666667 0.0000000000 + 22 0.1564490307 0.3403926624 0.0000000000 + 23 0.3071796770 0.6000000000 0.0000000000 + 24 0.1732050808 0.5000000000 0.0000000000 + 25 1.0000000000 1.0000000000 0.0000000000 + 26 0.0000000000 0.0000000000 0.0000000000 + 27 0.8000000000 1.0000000000 0.0000000000 + 28 0.0000000000 0.2000000000 0.0000000000 + 29 0.3077522095 0.8066666667 0.0000000000 + 30 0.0000000000 0.4000000000 0.0000000000 + 31 0.6000000000 1.0000000000 0.0000000000 + 32 0.1646894945 0.7177777778 0.0000000000 + 33 0.0000000000 0.6000000000 0.0000000000 + 34 0.4000000000 1.0000000000 0.0000000000 + 35 -0.2000000000 0.0000000000 0.0000000000 + 36 -0.1776709006 0.2833333333 0.0000000000 + 37 -0.1732050808 0.5000000000 0.0000000000 + 38 0.2000000000 1.0000000000 0.0000000000 + 39 0.0000000000 0.8000000000 0.0000000000 + 40 -0.3464101615 0.2000000000 0.0000000000 + 41 -0.1776709006 0.7166666667 0.0000000000 + 42 -0.4000000000 0.0000000000 0.0000000000 + 43 -0.3464101615 0.4000000000 0.0000000000 + 44 0.0000000000 1.0000000000 0.0000000000 + 45 -0.3464101615 0.6000000000 0.0000000000 + 46 -0.5338992487 0.2836605520 0.0000000000 + 47 -0.2000000000 1.0000000000 0.0000000000 + 48 -0.3464101615 0.8000000000 0.0000000000 + 49 -0.5196152423 0.5000000000 0.0000000000 + 50 -0.6000000000 0.0000000000 0.0000000000 + 51 -0.5140108873 0.7571428571 0.0000000000 + 52 -0.6981396042 0.2019633120 0.0000000000 + 53 -0.4000000000 1.0000000000 0.0000000000 + 54 -0.6928203230 0.4000000000 0.0000000000 + 55 -0.6928203230 0.6000000000 0.0000000000 + 56 -0.8000000000 0.0000000000 0.0000000000 + 57 -0.8435509693 0.3403926624 0.0000000000 + 58 -0.6884474276 0.8147619048 0.0000000000 + 59 -0.6000000000 1.0000000000 0.0000000000 + 60 -0.8267949192 0.5000000000 0.0000000000 + 61 -0.8354059275 0.7166666667 0.0000000000 + 62 -1.0000000000 0.0000000000 0.0000000000 + 63 -1.0000000000 0.2000000000 0.0000000000 + 64 -1.0000000000 0.4000000000 0.0000000000 + 65 -0.8000000000 1.0000000000 0.0000000000 + 66 -1.0000000000 0.6000000000 0.0000000000 + 67 -1.0000000000 0.8000000000 0.0000000000 + 68 -1.0000000000 1.0000000000 0.0000000000 +End Nodes + + +Begin Elements GeoTransientThermalElement2D3N + 1 1 62 56 63 + 2 1 33 39 41 + 3 1 67 66 61 + 4 1 41 39 47 + 5 1 33 41 37 + 6 1 61 66 60 + 7 1 37 41 45 + 8 1 33 37 30 + 9 1 60 66 64 + 10 1 45 41 48 + 11 1 30 37 36 + 12 1 48 41 47 + 13 1 45 48 51 + 14 1 36 37 43 + 15 1 51 53 59 + 16 1 45 51 49 + 17 1 43 37 45 + 18 1 49 51 55 + 19 1 45 49 43 + 20 1 55 51 58 + 21 1 49 55 54 + 22 1 43 49 46 + 23 1 55 58 61 + 24 1 61 58 65 + 25 1 55 61 60 + 26 1 55 60 54 + 27 1 54 60 57 + 28 1 57 60 64 + 29 1 57 64 63 + 30 1 57 63 52 + 31 1 54 57 52 + 32 1 52 63 56 + 33 1 54 52 46 + 34 1 46 49 54 + 35 1 43 46 40 + 36 1 40 46 50 + 37 1 43 40 36 + 38 1 36 40 35 + 39 1 35 26 28 + 40 1 53 51 48 + 41 1 50 42 40 + 42 1 44 47 39 + 43 1 28 30 36 + 44 1 28 36 35 + 45 1 65 68 67 + 46 1 56 50 52 + 47 1 59 65 58 + 48 1 58 51 59 + 49 1 42 35 40 + 50 1 47 53 48 + 51 1 67 61 65 + 52 1 46 52 50 + 53 1 26 18 28 + 54 1 12 19 16 + 55 1 39 33 32 + 56 1 16 19 27 + 57 1 12 16 9 + 58 1 32 33 24 + 59 1 9 16 13 + 60 1 12 9 7 + 61 1 24 33 30 + 62 1 13 16 20 + 63 1 7 9 4 + 64 1 20 16 27 + 65 1 13 20 21 + 66 1 4 9 8 + 67 1 21 20 34 + 68 1 13 21 14 + 69 1 8 9 13 + 70 1 14 21 23 + 71 1 13 14 8 + 72 1 23 21 29 + 73 1 14 23 17 + 74 1 8 14 10 + 75 1 23 29 32 + 76 1 32 29 38 + 77 1 23 32 24 + 78 1 23 24 17 + 79 1 17 24 22 + 80 1 22 24 30 + 81 1 22 30 28 + 82 1 22 28 15 + 83 1 17 22 15 + 84 1 15 28 18 + 85 1 17 15 10 + 86 1 10 14 17 + 87 1 8 10 5 + 88 1 5 10 6 + 89 1 8 5 4 + 90 1 4 5 2 + 91 1 2 1 3 + 92 1 31 34 20 + 93 1 11 6 10 + 94 1 25 27 19 + 95 1 3 7 4 + 96 1 3 4 2 + 97 1 38 44 39 + 98 1 18 11 15 + 99 1 34 38 29 + 100 1 29 21 34 + 101 1 6 2 5 + 102 1 27 31 20 + 103 1 39 32 38 + 104 1 10 15 11 +End Elements + + +Begin Elements GeoTransientThermalLineElement2D2N + 105 2 26 28 + 106 2 28 30 + 107 2 30 33 + 108 2 33 39 + 109 2 39 44 +End Elements + + +Begin Conditions GeoThermalPointFluxCondition2D1N + 1 2 26 + 2 2 44 +End Conditions + + +Begin SubModelPart soil + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart filter + Begin SubModelPartNodes + 26 + 28 + 30 + 33 + 39 + 44 + End SubModelPartNodes + Begin SubModelPartElements + 105 + 106 + 107 + 108 + 109 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart initial + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart right + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 3 + 7 + 12 + 19 + 25 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart left + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 62 + 63 + 64 + 66 + 67 + 68 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart pipe_top + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 44 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 2 + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart pipe_bottom + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 26 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 1 + End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/ProjectParameters.json new file mode 100644 index 000000000000..87d5dc134492 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/ProjectParameters.json @@ -0,0 +1,163 @@ +{ + "problem_data": { + "problem_name" : "test_thermal_filter_element_2D3N", + "start_time" : 0.0, + "end_time" : 8640000.0, + "echo_level" : 0, + "parallel_type" : "OpenMP", + "number_of_threads" : 1 + }, + "solver_settings": { + "solver_type" : "T", + "model_part_name" : "PorousDomain", + "domain_size" : 2, + "model_import_settings" : { + "input_type" : "mdpa", + "input_filename" : "test_thermal_filter_element_2D3N" + }, + "material_import_settings" : { + "materials_filename" : "../Common/MaterialParameters.json" + }, + "time_stepping" : { + "time_step" : 3600, + "max_delta_time_factor" : 1000 + }, + "buffer_size" : 2, + "echo_level" : 0, + "clear_storage" : false, + "compute_reactions" : false, + "move_mesh_flag" : false, + "reform_dofs_at_each_step" : false, + "nodal_smoothing" : false, + "block_builder" : true, + "solution_type" : "Transient_Heat_Transfer", + "scheme_type" : "Backward_Euler", + "reset_displacements" : false, + "newmark_beta" : 0.25, + "newmark_gamma" : 0.5, + "newmark_theta" : 0.5, + "rayleigh_m" : 0.0, + "rayleigh_k" : 0.0, + "strategy_type" : "newton_raphson", + "convergence_criterion" : "temperature_criterion", + "temperature_relative_tolerance" : 1.0E-4, + "temperature_absolute_tolerance" : 1.0E-9, + "residual_relative_tolerance" : 1.0E-4, + "residual_absolute_tolerance" : 1.0E-9, + "min_iterations" : 2, + "max_iterations" : 15, + "number_cycles" : 2, + "reduction_factor" : 0.5, + "increase_factor" : 2.0, + "desired_iterations" : 2, + "max_radius_factor" : 10.0, + "min_radius_factor" : 0.1, + "calculate_reactions" : true, + "max_line_search_iterations" : 5, + "first_alpha_value" : 0.5, + "second_alpha_value" : 1.0, + "min_alpha" : 0.1, + "max_alpha" : 2.0, + "line_search_tolerance" : 0.5, + "rotation_dofs" : true, + "linear_solver_settings" : { + "solver_type" : "bicgstab", + "tolerance" : 1.0e-6, + "max_iteration" : 1000, + "scaling" : true, + "preconditioner_type" : "ilu0" + }, + "problem_domain_sub_model_part_list" : ["filter","soil"], + "processes_sub_model_part_list" : ["initial","right","left","pipe_top","pipe_bottom"], + "body_domain_sub_model_part_list" : ["filter","soil"] + }, + "output_processes": { + "gid_output": [{ + "python_module" : "gid_output_process", + "kratos_module" : "KratosMultiphysics", + "process_name" : "GiDOutputProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.soil", + "output_name" : "test_thermal_filter_element_2D3N", + "postprocess_parameters" : { + "result_file_configuration" : { + "gidpost_flags" : { + "WriteDeformedMeshFlag" : "WriteUndeformed", + "WriteConditionsFlag" : "WriteElementsOnly", + "GiDPostMode" : "GiD_PostAscii", + "MultiFileFlag" : "SingleFile" + }, + "file_label" : "step", + "output_control_type" : "step", + "output_interval" : 1, + "body_output" : true, + "node_output" : false, + "skin_output" : false, + "plane_output" : [], + "nodal_results" : ["TEMPERATURE"], + "gauss_point_results" : [] + }, + "point_data_configuration" : [] + } + } + }] + }, + "processes": { + "constraints_process_list": [{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.initial", + "variable_name" : "TEMPERATURE", + "is_fixed" : false, + "value" : 0.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name" : "PorousDomain.right", + "variable_name" : "TEMPERATURE", + "is_fixed" : true, + "value" : 0.0, + "table" : 0 + } + },{ + "python_module" : "apply_scalar_constraint_table_process", + "kratos_module" : "KratosMultiphysics.GeoMechanicsApplication", + "process_name" : "ApplyScalarConstraintTableProcess", + "Parameters" : { + "model_part_name" : "PorousDomain.left", + "variable_name" : "TEMPERATURE", + "is_fixed" : true, + "value" : 0.0, + "table" : 0 + } + }], + "loads_process_list": [{ + "python_module": "apply_scalar_constraint_table_process", + "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", + "process_name": "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name": "PorousDomain.pipe_top", + "variable_name": "NORMAL_HEAT_FLUX", + "value": 100.0, + "table": 0 + } + },{ + "python_module": "apply_scalar_constraint_table_process", + "kratos_module": "KratosMultiphysics.GeoMechanicsApplication", + "process_name": "ApplyScalarConstraintTableProcess", + "Parameters": { + "model_part_name": "PorousDomain.pipe_bottom", + "variable_name": "NORMAL_HEAT_FLUX", + "value": 100.0, + "table": 0 + } + }], + "auxiliar_process_list": [] + } +} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/test_thermal_filter_element_2D3N.mdpa b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/test_thermal_filter_element_2D3N.mdpa new file mode 100644 index 000000000000..3d4e8b907ff9 --- /dev/null +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_filter_element/test_thermal_filter_element_2D3N/test_thermal_filter_element_2D3N.mdpa @@ -0,0 +1,1169 @@ +Begin Properties 1 +End Properties + +Begin Properties 2 +End Properties + +Begin Nodes + 1 1.0000000000 0.0000000000 0.0000000000 + 2 0.9000000000 0.0000000000 0.0000000000 + 3 1.0000000000 0.1000000000 0.0000000000 + 4 0.9000000000 0.1000000000 0.0000000000 + 5 0.8000000000 0.0000000000 0.0000000000 + 6 1.0000000000 0.2000000000 0.0000000000 + 7 0.8111645497 0.1416666667 0.0000000000 + 8 0.9111645497 0.2416666667 0.0000000000 + 9 0.7267949192 0.1000000000 0.0000000000 + 10 0.7000000000 0.0000000000 0.0000000000 + 11 1.0000000000 0.3000000000 0.0000000000 + 12 0.8223290994 0.2833333333 0.0000000000 + 13 0.9111645497 0.3416666667 0.0000000000 + 14 0.7379594689 0.2416666667 0.0000000000 + 15 0.6267949192 0.1000000000 0.0000000000 + 16 0.6535898385 0.2000000000 0.0000000000 + 17 0.6000000000 0.0000000000 0.0000000000 + 18 1.0000000000 0.4000000000 0.0000000000 + 19 0.8245620093 0.3916666667 0.0000000000 + 20 0.7379594689 0.3416666667 0.0000000000 + 21 0.6535898385 0.3000000000 0.0000000000 + 22 0.9133974596 0.4500000000 0.0000000000 + 23 0.5426146077 0.1215688080 0.0000000000 + 24 0.5694095269 0.2215688080 0.0000000000 + 25 1.0000000000 0.5000000000 0.0000000000 + 26 0.5000000000 0.0000000000 0.0000000000 + 27 0.7401923789 0.4500000000 0.0000000000 + 28 0.6535898385 0.4000000000 0.0000000000 + 29 0.8267949192 0.5000000000 0.0000000000 + 30 0.5694095269 0.3215688080 0.0000000000 + 31 0.9133974596 0.5500000000 0.0000000000 + 32 0.4852292154 0.2431376160 0.0000000000 + 33 0.4426146077 0.1215688080 0.0000000000 + 34 0.4000000000 0.0000000000 0.0000000000 + 35 1.0000000000 0.6000000000 0.0000000000 + 36 0.6535898385 0.5000000000 0.0000000000 + 37 0.7401923789 0.5500000000 0.0000000000 + 38 0.5669872981 0.4500000000 0.0000000000 + 39 0.8245620093 0.6083333333 0.0000000000 + 40 0.4828069865 0.3715688080 0.0000000000 + 41 0.3935448056 0.2225504640 0.0000000000 + 42 0.3509301979 0.1009816560 0.0000000000 + 43 0.9111645497 0.6583333333 0.0000000000 + 44 0.3962044462 0.3215688080 0.0000000000 + 45 0.6535898385 0.6000000000 0.0000000000 + 46 0.5669872981 0.5500000000 0.0000000000 + 47 0.3000000000 0.0000000000 0.0000000000 + 48 1.0000000000 0.7000000000 0.0000000000 + 49 0.7379594689 0.6583333333 0.0000000000 + 50 0.4803847577 0.5000000000 0.0000000000 + 51 0.3018603958 0.2019633120 0.0000000000 + 52 0.8223290994 0.7166666667 0.0000000000 + 53 0.3937822174 0.4500000000 0.0000000000 + 54 0.2509301979 0.1009816560 0.0000000000 + 55 0.3045200364 0.3009816560 0.0000000000 + 56 0.9111645497 0.7583333333 0.0000000000 + 57 0.6535898385 0.7000000000 0.0000000000 + 58 0.5602885683 0.6583333333 0.0000000000 + 59 0.3071796770 0.4000000000 0.0000000000 + 60 0.2000000000 0.0000000000 0.0000000000 + 61 1.0000000000 0.8000000000 0.0000000000 + 62 0.7379594689 0.7583333333 0.0000000000 + 63 0.4736860279 0.6083333333 0.0000000000 + 64 0.2291547133 0.2711779872 0.0000000000 + 65 0.3937822174 0.5500000000 0.0000000000 + 66 0.2318143538 0.3701963312 0.0000000000 + 67 0.3071796770 0.5000000000 0.0000000000 + 68 0.6535898385 0.8000000000 0.0000000000 + 69 0.1509301979 0.2009816560 0.0000000000 + 70 0.5602885683 0.7583333333 0.0000000000 + 71 0.8111645497 0.8583333333 0.0000000000 + 72 0.2401923789 0.4500000000 0.0000000000 + 73 0.4669872981 0.7166666667 0.0000000000 + 74 0.3870834875 0.6583333333 0.0000000000 + 75 0.1000000000 0.0000000000 0.0000000000 + 76 1.0000000000 0.9000000000 0.0000000000 + 77 0.1000000000 0.1000000000 0.0000000000 + 78 0.9000000000 0.9000000000 0.0000000000 + 79 0.1564490307 0.3403926624 0.0000000000 + 80 0.3071796770 0.6000000000 0.0000000000 + 81 0.1648270557 0.4201963312 0.0000000000 + 82 0.2401923789 0.5500000000 0.0000000000 + 83 0.7267949192 0.9000000000 0.0000000000 + 84 0.0782245154 0.2701963312 0.0000000000 + 85 0.1732050808 0.5000000000 0.0000000000 + 86 0.6267949192 0.9000000000 0.0000000000 + 87 0.3873697538 0.7616666667 0.0000000000 + 88 0.3074659432 0.7033333333 0.0000000000 + 89 0.0782245154 0.3701963312 0.0000000000 + 90 1.0000000000 1.0000000000 0.0000000000 + 91 0.0000000000 0.0000000000 0.0000000000 + 92 0.0000000000 0.1000000000 0.0000000000 + 93 0.9000000000 1.0000000000 0.0000000000 + 94 0.2359345858 0.6588888889 0.0000000000 + 95 0.5267949192 0.9000000000 0.0000000000 + 96 0.0866025404 0.4500000000 0.0000000000 + 97 0.8000000000 1.0000000000 0.0000000000 + 98 0.0000000000 0.2000000000 0.0000000000 + 99 0.4334936491 0.8583333333 0.0000000000 + 100 0.1689472876 0.6088888889 0.0000000000 + 101 0.0000000000 0.3000000000 0.0000000000 + 102 0.7000000000 1.0000000000 0.0000000000 + 103 0.3077522095 0.8066666667 0.0000000000 + 104 0.0866025404 0.5500000000 0.0000000000 + 105 0.0000000000 0.4000000000 0.0000000000 + 106 0.6000000000 1.0000000000 0.0000000000 + 107 0.2362208520 0.7622222222 0.0000000000 + 108 -0.1000000000 0.0000000000 0.0000000000 + 109 0.1646894945 0.7177777778 0.0000000000 + 110 -0.1000000000 0.1000000000 0.0000000000 + 111 0.3538761048 0.9033333333 0.0000000000 + 112 -0.0888354503 0.2416666667 0.0000000000 + 113 0.0000000000 0.5000000000 0.0000000000 + 114 0.5000000000 1.0000000000 0.0000000000 + 115 0.0823447473 0.6588888889 0.0000000000 + 116 -0.0888354503 0.3416666667 0.0000000000 + 117 0.0000000000 0.6000000000 0.0000000000 + 118 0.4000000000 1.0000000000 0.0000000000 + 119 0.2538761048 0.9033333333 0.0000000000 + 120 -0.0866025404 0.4500000000 0.0000000000 + 121 0.1823447473 0.8588888889 0.0000000000 + 122 0.0823447473 0.7588888889 0.0000000000 + 123 -0.1888354503 0.1416666667 0.0000000000 + 124 -0.2000000000 0.0000000000 0.0000000000 + 125 -0.1776709006 0.2833333333 0.0000000000 + 126 -0.0866025404 0.5500000000 0.0000000000 + 127 0.0000000000 0.7000000000 0.0000000000 + 128 0.3000000000 1.0000000000 0.0000000000 + 129 -0.1754379907 0.3916666667 0.0000000000 + 130 -0.0888354503 0.6583333333 0.0000000000 + 131 0.1000000000 0.9000000000 0.0000000000 + 132 -0.1732050808 0.5000000000 0.0000000000 + 133 -0.2732050808 0.1000000000 0.0000000000 + 134 0.0000000000 0.8000000000 0.0000000000 + 135 0.2000000000 1.0000000000 0.0000000000 + 136 -0.2620405311 0.2416666667 0.0000000000 + 137 -0.3000000000 0.0000000000 0.0000000000 + 138 -0.2620405311 0.3416666667 0.0000000000 + 139 -0.1754379907 0.6083333333 0.0000000000 + 140 -0.0888354503 0.7583333333 0.0000000000 + 141 -0.2598076211 0.4500000000 0.0000000000 + 142 0.0000000000 0.9000000000 0.0000000000 + 143 0.1000000000 1.0000000000 0.0000000000 + 144 -0.3464101615 0.2000000000 0.0000000000 + 145 -0.2598076211 0.5500000000 0.0000000000 + 146 -0.3732050808 0.1000000000 0.0000000000 + 147 -0.1776709006 0.7166666667 0.0000000000 + 148 -0.3464101615 0.3000000000 0.0000000000 + 149 -0.4000000000 0.0000000000 0.0000000000 + 150 -0.3464101615 0.4000000000 0.0000000000 + 151 0.0000000000 1.0000000000 0.0000000000 + 152 -0.1000000000 0.9000000000 0.0000000000 + 153 -0.2620405311 0.6583333333 0.0000000000 + 154 -0.3464101615 0.5000000000 0.0000000000 + 155 -0.4401547051 0.2418302760 0.0000000000 + 156 -0.1888354503 0.8583333333 0.0000000000 + 157 -0.2620405311 0.7583333333 0.0000000000 + 158 -0.3464101615 0.6000000000 0.0000000000 + 159 -0.4732050808 0.1000000000 0.0000000000 + 160 -0.4401547051 0.3418302760 0.0000000000 + 161 -0.1000000000 1.0000000000 0.0000000000 + 162 -0.5000000000 0.0000000000 0.0000000000 + 163 -0.4330127019 0.4500000000 0.0000000000 + 164 -0.3464101615 0.7000000000 0.0000000000 + 165 -0.4330127019 0.5500000000 0.0000000000 + 166 -0.2732050808 0.9000000000 0.0000000000 + 167 -0.5338992487 0.2836605520 0.0000000000 + 168 -0.2000000000 1.0000000000 0.0000000000 + 169 -0.3464101615 0.8000000000 0.0000000000 + 170 -0.5669496244 0.1418302760 0.0000000000 + 171 -0.5267572455 0.3918302760 0.0000000000 + 172 -0.4302105244 0.6785714286 0.0000000000 + 173 -0.5196152423 0.5000000000 0.0000000000 + 174 -0.6000000000 0.0000000000 0.0000000000 + 175 -0.4302105244 0.7785714286 0.0000000000 + 176 -0.6160194265 0.2428119320 0.0000000000 + 177 -0.3000000000 1.0000000000 0.0000000000 + 178 -0.3732050808 0.9000000000 0.0000000000 + 179 -0.5168130648 0.6285714286 0.0000000000 + 180 -0.6133597859 0.3418302760 0.0000000000 + 181 -0.6490698021 0.1009816560 0.0000000000 + 182 -0.6062177826 0.4500000000 0.0000000000 + 183 -0.5140108873 0.7571428571 0.0000000000 + 184 -0.6062177826 0.5500000000 0.0000000000 + 185 -0.7000000000 0.0000000000 0.0000000000 + 186 -0.4570054437 0.8785714286 0.0000000000 + 187 -0.6981396042 0.2019633120 0.0000000000 + 188 -0.4000000000 1.0000000000 0.0000000000 + 189 -0.6954799636 0.3009816560 0.0000000000 + 190 -0.6928203230 0.4000000000 0.0000000000 + 191 -0.6034156052 0.6785714286 0.0000000000 + 192 -0.7490698021 0.1009816560 0.0000000000 + 193 -0.6928203230 0.5000000000 0.0000000000 + 194 -0.6012291575 0.7859523810 0.0000000000 + 195 -0.5570054437 0.8785714286 0.0000000000 + 196 -0.7708452867 0.2711779872 0.0000000000 + 197 -0.6928203230 0.6000000000 0.0000000000 + 198 -0.8000000000 0.0000000000 0.0000000000 + 199 -0.5000000000 1.0000000000 0.0000000000 + 200 -0.7681856462 0.3701963312 0.0000000000 + 201 -0.7598076211 0.4500000000 0.0000000000 + 202 -0.6906338753 0.7073809524 0.0000000000 + 203 -0.7598076211 0.5500000000 0.0000000000 + 204 -0.8490698021 0.2009816560 0.0000000000 + 205 -0.8435509693 0.3403926624 0.0000000000 + 206 -0.6884474276 0.8147619048 0.0000000000 + 207 -0.6442237138 0.9073809524 0.0000000000 + 208 -0.8351729443 0.4201963312 0.0000000000 + 209 -0.7641131253 0.6583333333 0.0000000000 + 210 -0.6000000000 1.0000000000 0.0000000000 + 211 -0.8267949192 0.5000000000 0.0000000000 + 212 -0.9000000000 0.0000000000 0.0000000000 + 213 -0.9000000000 0.1000000000 0.0000000000 + 214 -0.7619266776 0.7657142857 0.0000000000 + 215 -0.8311004234 0.6083333333 0.0000000000 + 216 -0.9217754846 0.2701963312 0.0000000000 + 217 -0.9217754846 0.3701963312 0.0000000000 + 218 -0.9133974596 0.4500000000 0.0000000000 + 219 -0.7442237138 0.9073809524 0.0000000000 + 220 -0.8354059275 0.7166666667 0.0000000000 + 221 -0.7000000000 1.0000000000 0.0000000000 + 222 -0.9133974596 0.5500000000 0.0000000000 + 223 -1.0000000000 0.0000000000 0.0000000000 + 224 -1.0000000000 0.1000000000 0.0000000000 + 225 -1.0000000000 0.2000000000 0.0000000000 + 226 -0.8177029638 0.8583333333 0.0000000000 + 227 -1.0000000000 0.3000000000 0.0000000000 + 228 -0.9177029638 0.6583333333 0.0000000000 + 229 -1.0000000000 0.4000000000 0.0000000000 + 230 -0.8000000000 1.0000000000 0.0000000000 + 231 -1.0000000000 0.5000000000 0.0000000000 + 232 -0.9177029638 0.7583333333 0.0000000000 + 233 -1.0000000000 0.6000000000 0.0000000000 + 234 -0.9000000000 0.9000000000 0.0000000000 + 235 -1.0000000000 0.7000000000 0.0000000000 + 236 -0.9000000000 1.0000000000 0.0000000000 + 237 -1.0000000000 0.8000000000 0.0000000000 + 238 -1.0000000000 0.9000000000 0.0000000000 + 239 -1.0000000000 1.0000000000 0.0000000000 +End Nodes + + +Begin Elements GeoTransientThermalElement2D6N + 1 1 223 198 225 212 213 224 + 2 1 117 134 147 127 140 130 + 3 1 237 233 220 235 228 232 + 4 1 147 134 168 140 152 156 + 5 1 117 147 132 130 139 126 + 6 1 220 233 211 228 222 215 + 7 1 132 147 158 139 153 145 + 8 1 117 132 105 126 120 113 + 9 1 211 233 229 222 231 218 + 10 1 158 147 169 153 157 164 + 11 1 105 132 125 120 129 116 + 12 1 169 147 168 157 156 166 + 13 1 158 169 183 164 175 172 + 14 1 125 132 150 129 141 138 + 15 1 183 188 210 186 199 195 + 16 1 158 183 173 172 179 165 + 17 1 150 132 158 141 145 154 + 18 1 173 183 197 179 191 184 + 19 1 158 173 150 165 163 154 + 20 1 197 183 206 191 194 202 + 21 1 173 197 190 184 193 182 + 22 1 150 173 167 163 171 160 + 23 1 197 206 220 202 214 209 + 24 1 220 206 230 214 219 226 + 25 1 197 220 211 209 215 203 + 26 1 197 211 190 203 201 193 + 27 1 190 211 205 201 208 200 + 28 1 205 211 229 208 218 217 + 29 1 205 229 225 217 227 216 + 30 1 205 225 187 216 204 196 + 31 1 190 205 187 200 196 189 + 32 1 187 225 198 204 213 192 + 33 1 190 187 167 189 176 180 + 34 1 167 173 190 171 182 180 + 35 1 150 167 144 160 155 148 + 36 1 144 167 174 155 170 159 + 37 1 150 144 125 148 136 138 + 38 1 125 144 124 136 133 123 + 39 1 124 91 98 108 92 110 + 40 1 188 183 169 186 175 178 + 41 1 174 149 144 162 146 159 + 42 1 151 168 134 161 152 142 + 43 1 98 105 125 101 116 112 + 44 1 98 125 124 112 123 110 + 45 1 230 239 237 236 238 234 + 46 1 198 174 187 185 181 192 + 47 1 210 230 206 221 219 207 + 48 1 206 183 210 194 195 207 + 49 1 149 124 144 137 133 146 + 50 1 168 188 169 177 178 166 + 51 1 237 220 230 232 226 234 + 52 1 167 187 174 176 181 170 + 53 1 91 60 98 75 77 92 + 54 1 35 61 52 48 56 43 + 55 1 134 117 109 127 115 122 + 56 1 52 61 97 56 78 71 + 57 1 35 52 29 43 39 31 + 58 1 109 117 85 115 104 100 + 59 1 29 52 45 39 49 37 + 60 1 35 29 18 31 22 25 + 61 1 85 117 105 104 113 96 + 62 1 45 52 68 49 62 57 + 63 1 18 29 12 22 19 13 + 64 1 68 52 97 62 71 83 + 65 1 45 68 73 57 70 58 + 66 1 12 29 28 19 27 20 + 67 1 73 68 118 70 95 99 + 68 1 45 73 50 58 63 46 + 69 1 28 29 45 27 37 36 + 70 1 50 73 80 63 74 65 + 71 1 45 50 28 46 38 36 + 72 1 80 73 103 74 87 88 + 73 1 50 80 59 65 67 53 + 74 1 28 50 32 38 40 30 + 75 1 80 103 109 88 107 94 + 76 1 109 103 135 107 119 121 + 77 1 80 109 85 94 100 82 + 78 1 80 85 59 82 72 67 + 79 1 59 85 79 72 81 66 + 80 1 79 85 105 81 96 89 + 81 1 79 105 98 89 101 84 + 82 1 79 98 51 84 69 64 + 83 1 59 79 51 66 64 55 + 84 1 51 98 60 69 77 54 + 85 1 59 51 32 55 41 44 + 86 1 32 50 59 40 53 44 + 87 1 28 32 16 30 24 21 + 88 1 16 32 17 24 23 15 + 89 1 28 16 12 21 14 20 + 90 1 12 16 5 14 9 7 + 91 1 5 1 6 2 3 4 + 92 1 106 118 68 114 95 86 + 93 1 34 17 32 26 23 33 + 94 1 90 97 61 93 78 76 + 95 1 6 18 12 11 13 8 + 96 1 6 12 5 8 7 4 + 97 1 135 151 134 143 142 131 + 98 1 60 34 51 47 42 54 + 99 1 118 135 103 128 119 111 + 100 1 103 73 118 87 99 111 + 101 1 17 5 16 10 9 15 + 102 1 97 106 68 102 86 83 + 103 1 134 109 135 122 121 131 + 104 1 32 51 34 41 42 33 +End Elements + + +Begin Elements GeoTransientThermalLineElement2D3N + 105 2 91 98 92 + 106 2 98 105 101 + 107 2 105 117 113 + 108 2 117 134 127 + 109 2 134 151 142 +End Elements + + +Begin Conditions GeoThermalPointFluxCondition2D1N + 1 2 91 + 2 2 151 +End Conditions + + +Begin SubModelPart soil + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + 130 + 131 + 132 + 133 + 134 + 135 + 136 + 137 + 138 + 139 + 140 + 141 + 142 + 143 + 144 + 145 + 146 + 147 + 148 + 149 + 150 + 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + 184 + 185 + 186 + 187 + 188 + 189 + 190 + 191 + 192 + 193 + 194 + 195 + 196 + 197 + 198 + 199 + 200 + 201 + 202 + 203 + 204 + 205 + 206 + 207 + 208 + 209 + 210 + 211 + 212 + 213 + 214 + 215 + 216 + 217 + 218 + 219 + 220 + 221 + 222 + 223 + 224 + 225 + 226 + 227 + 228 + 229 + 230 + 231 + 232 + 233 + 234 + 235 + 236 + 237 + 238 + 239 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart filter + Begin SubModelPartNodes + 91 + 92 + 98 + 101 + 105 + 113 + 117 + 127 + 134 + 142 + 151 + End SubModelPartNodes + Begin SubModelPartElements + 105 + 106 + 107 + 108 + 109 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart initial + Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + 105 + 106 + 107 + 108 + 109 + 110 + 111 + 112 + 113 + 114 + 115 + 116 + 117 + 118 + 119 + 120 + 121 + 122 + 123 + 124 + 125 + 126 + 127 + 128 + 129 + 130 + 131 + 132 + 133 + 134 + 135 + 136 + 137 + 138 + 139 + 140 + 141 + 142 + 143 + 144 + 145 + 146 + 147 + 148 + 149 + 150 + 151 + 152 + 153 + 154 + 155 + 156 + 157 + 158 + 159 + 160 + 161 + 162 + 163 + 164 + 165 + 166 + 167 + 168 + 169 + 170 + 171 + 172 + 173 + 174 + 175 + 176 + 177 + 178 + 179 + 180 + 181 + 182 + 183 + 184 + 185 + 186 + 187 + 188 + 189 + 190 + 191 + 192 + 193 + 194 + 195 + 196 + 197 + 198 + 199 + 200 + 201 + 202 + 203 + 204 + 205 + 206 + 207 + 208 + 209 + 210 + 211 + 212 + 213 + 214 + 215 + 216 + 217 + 218 + 219 + 220 + 221 + 222 + 223 + 224 + 225 + 226 + 227 + 228 + 229 + 230 + 231 + 232 + 233 + 234 + 235 + 236 + 237 + 238 + 239 + End SubModelPartNodes + Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + 29 + 30 + 31 + 32 + 33 + 34 + 35 + 36 + 37 + 38 + 39 + 40 + 41 + 42 + 43 + 44 + 45 + 46 + 47 + 48 + 49 + 50 + 51 + 52 + 53 + 54 + 55 + 56 + 57 + 58 + 59 + 60 + 61 + 62 + 63 + 64 + 65 + 66 + 67 + 68 + 69 + 70 + 71 + 72 + 73 + 74 + 75 + 76 + 77 + 78 + 79 + 80 + 81 + 82 + 83 + 84 + 85 + 86 + 87 + 88 + 89 + 90 + 91 + 92 + 93 + 94 + 95 + 96 + 97 + 98 + 99 + 100 + 101 + 102 + 103 + 104 + End SubModelPartElements +End SubModelPart + + +Begin SubModelPart right + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 1 + 3 + 6 + 11 + 18 + 25 + 35 + 48 + 61 + 76 + 90 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart left + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 223 + 224 + 225 + 227 + 229 + 231 + 233 + 235 + 237 + 238 + 239 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + End SubModelPartConditions +End SubModelPart + +Begin SubModelPart pipe_top + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 151 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 2 + End SubModelPartConditions +End SubModelPart + + +Begin SubModelPart pipe_bottom + Begin SubModelPartTables + End SubModelPartTables + Begin SubModelPartNodes + 91 + End SubModelPartNodes + Begin SubModelPartElements + End SubModelPartElements + Begin SubModelPartConditions + 1 + End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters2D.json similarity index 88% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters2D.json index 26097783ea07..0e6dc4222b37 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters3D.json similarity index 90% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters3D.json index 6ba057e60986..d80d6e5a6629 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/ProjectParameters.json index 68848547f82a..c4221eae2c35 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/ProjectParameters.json index 3e4d2d93881a..a3c9af5af891 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D15N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/ProjectParameters.json index 174e3e0c2f43..eb7f039c8d1e 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D3N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/ProjectParameters.json index 4bcdbc1e2ac9..1327993821c8 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D3N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/ProjectParameters.json index bfc802d7b58b..fe5112268c04 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/ProjectParameters.json index ce934c620474..736549ba4094 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D6N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D6N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/ProjectParameters.json index 1dd29283da93..8982d6634197 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D8N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D8N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/ProjectParameters.json index 44cc1abd5073..616862a1b88c 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D9N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_2D9N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/ProjectParameters.json index 0d625005f806..e3a5161cc3f8 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_3D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 3600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/ProjectParameters.json index 5c07a792f741..ddf1b2d15dbe 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_fixed_temperature_3D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 3600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters2D.json similarity index 88% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters2D.json index 26097783ea07..0e6dc4222b37 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D15N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters3D.json similarity index 90% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters3D.json index 6ba057e60986..d80d6e5a6629 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_3D4N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/MaterialParameters.json deleted file mode 100644 index 72301b714494..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY": 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/ProjectParameters.json index f1c4cca96f6b..c4ea46d75d5e 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/ProjectParameters.json index 1a6a5c39e4d2..8b6907d1a4e2 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D15N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D15N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/ProjectParameters.json index 9f6b89b38193..2ab5b31eda84 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D3N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D3N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/ProjectParameters.json index 250b9bee25be..087448427c35 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/ProjectParameters.json index abdf36028ed1..2b17c561b8b4 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D6N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D6N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/ProjectParameters.json index d2aa043a2cc6..6413974b56e6 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D8N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D8N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/ProjectParameters.json index 2cd86f01a194..7c261b126feb 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_2D9N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_2D9N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/MaterialParameters.json deleted file mode 100644 index b5aaba0737b5..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/MaterialParameters.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_ZZ" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_YZ" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_XZ" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/ProjectParameters.json index 9c537d7bebbd..a5dcf0b6e575 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_3D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/MaterialParameters.json deleted file mode 100644 index b5aaba0737b5..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/MaterialParameters.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_ZZ" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_YZ" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_XZ" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/ProjectParameters.json index 387d6d974421..1a74437e72ba 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D20N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_3D20N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/MaterialParameters.json deleted file mode 100644 index b5aaba0737b5..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/MaterialParameters.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_ZZ" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_YZ" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_XZ" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/ProjectParameters.json index 267696653037..5c0a6eb6ec3d 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_3D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/MaterialParameters.json deleted file mode 100644 index b5aaba0737b5..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/MaterialParameters.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_ZZ" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_YZ" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_XZ" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/ProjectParameters.json index ca6e5bef96fb..78ffe664a21d 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux/test_thermal_heat_flux_3D8N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_thermal_heat_flux_3D8N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters2D.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters2D.json index 387473ce06bd..f33075bb6866 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters2D.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters3D.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters3D.json index 771b7b5290fd..f33075bb6866 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters3D.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_heat_flux_line_element/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters2D.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters2D.json index 51914a5a50a5..2410fc0e995c 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters2D.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.filter", "properties_id" : 1, "Material" : { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables" : { + "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650.0, "DENSITY_WATER" : 1000.0, "POROSITY" : 1.0, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters3D.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters3D.json index e5378614a18f..2410fc0e995c 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters3D.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_line_element/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name" : "PorousDomain.filter", "properties_id" : 1, "Material" : { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables" : { + "Variables" : { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650.0, "DENSITY_WATER" : 1000.0, "POROSITY" : 1.0, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters2D.json similarity index 88% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters2D.json index 26097783ea07..0e6dc4222b37 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters3D.json similarity index 90% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters3D.json index 6ba057e60986..d80d6e5a6629 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/ProjectParameters.json index eeed3af1ad85..eb092b1caee9 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/ProjectParameters.json index 9edaabeb0827..8db7310c8341 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D15N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D15N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/ProjectParameters.json index 04a6aa15ab82..e1b7cabc4481 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D3N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D3N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/ProjectParameters.json index 56d5dbc54bb6..11904d78f7e5 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/ProjectParameters.json index 517d50daabea..6d8cfbf037bd 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D6N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D6N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/ProjectParameters.json index 73198c2cb4c2..d81e96930e12 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D8N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D8N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/ProjectParameters.json index b7143d77c46e..06b99f5a885b 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_2D9N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_2D9N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/ProjectParameters.json index 40b09c63cbb0..efd6bdf9ead4 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_3D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 3600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/ProjectParameters.json index ba2a3effb220..84d46044af5e 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_fixed_temperature_3D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 3600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters2D.json similarity index 88% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters2D.json index 26097783ea07..0e6dc4222b37 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_thermal_fixed_temperature/test_thermal_fixed_temperature_2D3N_newmark/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters2D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters3D.json similarity index 90% rename from applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/MaterialParameters.json rename to applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters3D.json index 6ba057e60986..d80d6e5a6629 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_fixed_temperature/test_transient_thermal_fixed_temperature_3D4N/MaterialParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/Common/MaterialParameters3D.json @@ -3,10 +3,8 @@ "model_part_name": "PorousDomain.Soil", "properties_id": 1, "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, "Variables": { + "THERMAL_LAW_NAME" : "GeoThermalDispersionLaw", "DENSITY_SOLID" : 2650, "DENSITY_WATER" : 1000, "POROSITY" : 0.36, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/ProjectParameters.json index da7da0ac1302..3cecf7e3aa5c 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/ProjectParameters.json index f97cf46b1dc0..c15a2aef04ae 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D15N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D15N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/ProjectParameters.json index b0a81bc4ab29..0715808a5264 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D3N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D3N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/ProjectParameters.json index 8b43f6255998..2f61600c3d96 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/ProjectParameters.json index 73cf31566d08..942228bfa923 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D6N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D6N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/ProjectParameters.json index 295ae6436866..f9cfee37d042 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D8N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D8N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/MaterialParameters.json deleted file mode 100644 index 26097783ea07..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/MaterialParameters.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion2DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/ProjectParameters.json index d7c31991c90d..5e92b974e395 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_2D9N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_2D9N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters2D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D10N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D10N/ProjectParameters.json index 76beb15fdbc5..b7448d9153e0 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D10N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D10N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_3D10N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/MaterialParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/MaterialParameters.json deleted file mode 100644 index b5aaba0737b5..000000000000 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/MaterialParameters.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "properties": [{ - "model_part_name": "PorousDomain.Soil", - "properties_id": 1, - "Material": { - "constitutive_law": { - "name" : "GeoThermalDispersion3DLaw" - }, - "Variables": { - "DENSITY_SOLID" : 2650, - "DENSITY_WATER" : 1000, - "POROSITY" : 0.36, - "RETENTION_LAW" : "SaturatedLaw", - "SATURATED_SATURATION" : 1.0, - "SPECIFIC_HEAT_CAPACITY_SOLID" : 400.0, - "SPECIFIC_HEAT_CAPACITY_WATER" : 3795.0, - "THERMAL_CONDUCTIVITY_SOLID_XX" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_YY" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_ZZ" : 1.50, - "THERMAL_CONDUCTIVITY_SOLID_XY" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_YZ" : 0.0, - "THERMAL_CONDUCTIVITY_SOLID_XZ" : 0.0, - "THERMAL_CONDUCTIVITY_WATER" : 0.48 - }, - "Tables": {} - } - }] -} diff --git a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/ProjectParameters.json b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/ProjectParameters.json index 71568d695ff5..a182780f74f3 100644 --- a/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/ProjectParameters.json +++ b/applications/GeoMechanicsApplication/tests/test_thermal_element/test_transient_thermal_heat_flux/test_transient_thermal_heat_flux_3D4N/ProjectParameters.json @@ -16,7 +16,7 @@ "input_filename": "test_transient_thermal_heat_flux_3D4N" }, "material_import_settings": { - "materials_filename": "MaterialParameters.json" + "materials_filename": "../Common/MaterialParameters3D.json" }, "time_stepping": { "time_step": 600, diff --git a/applications/GeoMechanicsApplication/tests/test_transient_thermal.py b/applications/GeoMechanicsApplication/tests/test_transient_thermal.py index 54c4999ef460..b0f6d0a81057 100644 --- a/applications/GeoMechanicsApplication/tests/test_transient_thermal.py +++ b/applications/GeoMechanicsApplication/tests/test_transient_thermal.py @@ -263,6 +263,14 @@ def test_thermal_point_flux_3D2N(self): def test_thermal_point_flux_3D3N(self): temperature = self.simulate_thermal_case('test_thermal_heat_flux_line_element/test_thermal_point_flux_3D3N') self.assertAlmostEqual(self.etalon_value6, temperature[0]) + + def test_thermal_filter_element_2D2N(self): + temperature = self.simulate_thermal_case('test_thermal_filter_element/test_thermal_filter_element_2D2N') + self.assertAlmostEqual(34.65690605787046, temperature[22]) + + def test_thermal_filter_element_2D3N(self): + temperature = self.simulate_thermal_case('test_thermal_filter_element/test_thermal_filter_element_2D3N') + self.assertAlmostEqual(34.657035390578656, temperature[79]) if __name__ == '__main__': KratosUnittest.main() diff --git a/applications/MappingApplication/README.md b/applications/MappingApplication/README.md index 125540fbc8a8..c9540f44d137 100644 --- a/applications/MappingApplication/README.md +++ b/applications/MappingApplication/README.md @@ -27,6 +27,8 @@ The Mapping Application contains the core developments in mapping data between n - Nearest Neighbor - Nearest Element - Barycentric +- Metamappers + - 3D/2D metamapper (metamapper which obtains the solution for the 3D destination model part from the original 2D solution) - Mapping operations (see [here](#customizing-the-behavior-of-the-mapping-with-flags)) ### Dependencies @@ -116,6 +118,17 @@ mapper.InverseMap(KM.TEMPERATURE, KM.AMBIENT_TEMPERATURE) mapper.InverseMap(KM.VELOCITY, KM.MESH_VELOCITY) ``` +For the 3D/2D metamapper the settings to consider are the following, where `base_mapper` is the backend mapper to be considered. + +```json +mapper_params = KM.Parameters("""{ + "mapper_type" : "projection_3D_2D", + "base_mapper" : "nearest_neighbor", + "search_settings" : {}, + "echo_level" : 0 +}""") +``` + ### Advanced Usage The previous section introduced the basics of using the _MappingApplication_. The more advanced usage is explained in this section. diff --git a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_2D_law.cpp b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_2D_law.cpp index 1d6125870d36..aa66d7c1dfa8 100644 --- a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_2D_law.cpp +++ b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_2D_law.cpp @@ -45,6 +45,7 @@ void ElastoPlasticMohrCoulombCohesive2DLaw::InitializeMaterial( const Properties mPlasticStrainVector[1] = 0.0; mOldPlasticStrainVector[0] = 0.0; mOldPlasticStrainVector[1] = 0.0; + mSlipTendency = 0.0; } //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.cpp b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.cpp index 8a01ecf499bf..96f729dff1c7 100644 --- a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.cpp +++ b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.cpp @@ -97,6 +97,7 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::InitializeMaterial( const Properties mOldPlasticStrainVector[0] = 0.0; mOldPlasticStrainVector[1] = 0.0; mOldPlasticStrainVector[2] = 0.0; + mSlipTendency = 0.0; } //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- @@ -181,6 +182,18 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::FinalizeMaterialResponseCauchy (Para //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +double& ElastoPlasticMohrCoulombCohesive3DLaw::GetValue( const Variable& rThisVariable, double& rValue ) +{ + if (rThisVariable == SLIP_TENDENCY) + { + rValue = mSlipTendency; + } + + return rValue; +} + +//---------------------------------------------------------------------------------------- + Vector& ElastoPlasticMohrCoulombCohesive3DLaw::GetValue( const Variable& rThisVariable, Vector& rValue ) { rValue = mPlasticStrainVector; @@ -269,7 +282,10 @@ double ElastoPlasticMohrCoulombCohesive3DLaw::GetShearResultantStressVector(Vect // This method computes the traction vector and the plastic multiplier based on a Backward-Euler integration scheme. // The implementation does not consider any softening or hardening rule. -void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, Matrix& rConstitutiveMatrix, Vector& TrialStressVector, Matrix& ElasticConstitutiveMatrix, ConstitutiveLawVariables& rVariables, ElastoPlasticConstitutiveLawVariables& rEPlasticVariables, Parameters& rValues) +void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, Matrix& rConstitutiveMatrix, + Vector& TrialStressVector, Matrix& ElasticConstitutiveMatrix, + ConstitutiveLawVariables& rVariables, ElastoPlasticConstitutiveLawVariables& rEPlasticVariables, + Parameters& rValues) { // Get the size of the strain vector const Vector& StrainVector = rValues.GetStrainVector(); @@ -298,7 +314,10 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, rStressVector = TrialStressVector; // Get the shear resultant - double ts = this->GetShearResultantStressVector(rStressVector); + double ts = this->GetShearResultantStressVector(rStressVector); + + // Get the normal component of the stress vector + double tn = rStressVector[VoigtSize-1]; // Compute the normal to the plastic potential surface (np) and its derivative wrt to the stress vector this->DerivativesPlasticPotentialSurface(rStressVector, rVariables, rEPlasticVariables, rValues); @@ -327,6 +346,14 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, rConstitutiveMatrix(VoigtSize-1, VoigtSize-1) = 0.0; } + // Compute the slip tendency + if (rEPlasticVariables.YieldFunction_MC == 0.0) { + mSlipTendency = 1.0; + } + else { + mSlipTendency = abs(ts) / abs(c - tn*tanPhi); + } + } else if ((rEPlasticVariables.YieldFunction_MC > 0.0) && (rEPlasticVariables.YieldFunction_CutOff < 0.0)){ // ------ Return to the Mohr-Coulomb surface // Result from the product between n^T * Tel * np @@ -352,6 +379,9 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, noalias(rConstitutiveMatrix) = ElasticConstitutiveMatrix - outer_prod(Tel_np,Tel_n) / n_Tel_np; } + // Compute the slip tendency + mSlipTendency = 1.0; + }else{ // ------------------------------------------------------------------------------------------- Return to the point which both surfaces intersect // Compute the plastic multipliers @@ -371,6 +401,9 @@ void ElastoPlasticMohrCoulombCohesive3DLaw::ReturnMapping(Vector& rStressVector, if(Options.Is(ConstitutiveLaw::COMPUTE_CONSTITUTIVE_TENSOR)){ this->ConstitutiveMatrixInstersectionYieldSurfaces(rStressVector,rConstitutiveMatrix, rVariables); } + + // Compute the slip tendency + mSlipTendency = 1.0; } } diff --git a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.hpp b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.hpp index 138184fb05af..7033b6a7fee0 100644 --- a/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.hpp +++ b/applications/PoromechanicsApplication/custom_constitutive/interface_element_laws/elastoplastic_mohr_coulomb_cohesive_3D_law.hpp @@ -73,6 +73,8 @@ class KRATOS_API(POROMECHANICS_APPLICATION) ElastoPlasticMohrCoulombCohesive3DLa void FinalizeMaterialResponseCauchy(Parameters & rValues) override; //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + double& GetValue( const Variable& rThisVariable, double& rValue ) override; + Vector& GetValue( const Variable& rThisVariable, Vector& rValue ) override; void SetValue( const Variable& rThisVariable, @@ -108,11 +110,13 @@ class KRATOS_API(POROMECHANICS_APPLICATION) ElastoPlasticMohrCoulombCohesive3DLa // Vector normal to the plastic potential surface Vector np_MC; Vector np_TC; + }; // Member Variables - Vector mPlasticStrainVector; + Vector mPlasticStrainVector; Vector mOldPlasticStrainVector; + double mSlipTendency; //---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- diff --git a/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.cpp b/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.cpp index c84218800921..721ec4a48183 100644 --- a/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.cpp +++ b/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.cpp @@ -199,7 +199,17 @@ void UPlSmallStrainInterfaceElement::FinalizeSolutionStep( const // Auxiliar output variables unsigned int NumGPoints = mConstitutiveLawVector.size(); - std::vector JointWidthContainer(NumGPoints); + + // Define the variables to compute the nodal values + ExtrapolationVariables MyExtrapolationVariables; + + MyExtrapolationVariables.JointWidthContainer.resize(NumGPoints); + + MyExtrapolationVariables.MidPlaneLiquidPressureContainer.resize(NumGPoints); + this->CalculateOnIntegrationPoints(MID_PLANE_LIQUID_PRESSURE, MyExtrapolationVariables.MidPlaneLiquidPressureContainer, rCurrentProcessInfo); + + MyExtrapolationVariables.SlipTendencyContainer.resize(NumGPoints); + this->CalculateOnIntegrationPoints(SLIP_TENDENCY, MyExtrapolationVariables.SlipTendencyContainer, rCurrentProcessInfo); //Loop over integration points for ( unsigned int GPoint = 0; GPoint < NumGPoints; GPoint++ ) @@ -210,19 +220,19 @@ void UPlSmallStrainInterfaceElement::FinalizeSolutionStep( const noalias(StrainVector) = prod(RotationMatrix,RelDispVector); - JointWidthContainer[GPoint] = mInitialGap[GPoint] + StrainVector[TDim-1]; + MyExtrapolationVariables.JointWidthContainer[GPoint] = mInitialGap[GPoint] + StrainVector[TDim-1]; this->CheckAndCalculateJointWidth(JointWidth, ConstitutiveParameters, StrainVector[TDim-1], InitialJointWidth, GPoint); noalias(Np) = row(NContainer,GPoint); - //compute constitutive tensor and/or stresses + //Compute constitutive tensor and/or stresses mConstitutiveLawVector[GPoint]->FinalizeMaterialResponseCauchy(ConstitutiveParameters); } if(rCurrentProcessInfo[NODAL_SMOOTHING] == true) { - this->ExtrapolateGPValues(JointWidthContainer); + this->ExtrapolateGPValues(MyExtrapolationVariables); } KRATOS_CATCH( "" ) @@ -231,7 +241,7 @@ void UPlSmallStrainInterfaceElement::FinalizeSolutionStep( const //---------------------------------------------------------------------------------------- template< > -void UPlSmallStrainInterfaceElement<2,4>::ExtrapolateGPValues (const std::vector& JointWidthContainer) +void UPlSmallStrainInterfaceElement<2,4>::ExtrapolateGPValues (const ExtrapolationVariables& MyExtrapolationVariables) { array_1d DamageContainer; // 2 LobattoPoints @@ -245,10 +255,16 @@ void UPlSmallStrainInterfaceElement<2,4>::ExtrapolateGPValues (const std::vector const double& Area = rGeom.Area(); array_1d NodalJointWidth; - NodalJointWidth[0] = JointWidthContainer[0]*Area; - NodalJointWidth[1] = JointWidthContainer[1]*Area; - NodalJointWidth[2] = JointWidthContainer[1]*Area; - NodalJointWidth[3] = JointWidthContainer[0]*Area; + NodalJointWidth[0] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + NodalJointWidth[1] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[2] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[3] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + + array_1d NodalMidPlaneLiquidPressure; + NodalMidPlaneLiquidPressure[0] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; + NodalMidPlaneLiquidPressure[1] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[2] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[3] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; array_1d NodalDamage; NodalDamage[0] = DamageContainer[0]*Area; @@ -256,11 +272,19 @@ void UPlSmallStrainInterfaceElement<2,4>::ExtrapolateGPValues (const std::vector NodalDamage[2] = DamageContainer[1]*Area; NodalDamage[3] = DamageContainer[0]*Area; + array_1d NodalSlipTendency; + NodalSlipTendency[0] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + NodalSlipTendency[1] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[2] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[3] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + for(unsigned int i = 0; i < 4; i++) //NumNodes { rGeom[i].SetLock(); rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_WIDTH) += NodalJointWidth[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE) += NodalMidPlaneLiquidPressure[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_DAMAGE) += NodalDamage[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_SLIP_TENDENCY) += NodalSlipTendency[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_AREA) += Area; rGeom[i].UnSetLock(); } @@ -269,7 +293,7 @@ void UPlSmallStrainInterfaceElement<2,4>::ExtrapolateGPValues (const std::vector //---------------------------------------------------------------------------------------- template< > -void UPlSmallStrainInterfaceElement<3,6>::ExtrapolateGPValues (const std::vector& JointWidthContainer) +void UPlSmallStrainInterfaceElement<3,6>::ExtrapolateGPValues (const ExtrapolationVariables& MyExtrapolationVariables) { array_1d DamageContainer; // 3 LobattoPoints @@ -283,12 +307,20 @@ void UPlSmallStrainInterfaceElement<3,6>::ExtrapolateGPValues (const std::vector const double& Area = rGeom.Area(); array_1d NodalJointWidth; - NodalJointWidth[0] = JointWidthContainer[0]*Area; - NodalJointWidth[1] = JointWidthContainer[1]*Area; - NodalJointWidth[2] = JointWidthContainer[2]*Area; - NodalJointWidth[3] = JointWidthContainer[0]*Area; - NodalJointWidth[4] = JointWidthContainer[1]*Area; - NodalJointWidth[5] = JointWidthContainer[2]*Area; + NodalJointWidth[0] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + NodalJointWidth[1] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[2] = MyExtrapolationVariables.JointWidthContainer[2]*Area; + NodalJointWidth[3] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + NodalJointWidth[4] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[5] = MyExtrapolationVariables.JointWidthContainer[2]*Area; + + array_1d NodalMidPlaneLiquidPressure; + NodalMidPlaneLiquidPressure[0] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; + NodalMidPlaneLiquidPressure[1] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[2] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[2]*Area; + NodalMidPlaneLiquidPressure[3] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; + NodalMidPlaneLiquidPressure[4] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[5] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[2]*Area; array_1d NodalDamage; NodalDamage[0] = DamageContainer[0]*Area; @@ -298,11 +330,21 @@ void UPlSmallStrainInterfaceElement<3,6>::ExtrapolateGPValues (const std::vector NodalDamage[4] = DamageContainer[1]*Area; NodalDamage[5] = DamageContainer[2]*Area; + array_1d NodalSlipTendency; + NodalSlipTendency[0] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + NodalSlipTendency[1] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[2] = MyExtrapolationVariables.SlipTendencyContainer[2]*Area; + NodalSlipTendency[3] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + NodalSlipTendency[4] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[5] = MyExtrapolationVariables.SlipTendencyContainer[2]*Area; + for(unsigned int i = 0; i < 6; i++) //NumNodes { rGeom[i].SetLock(); rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_WIDTH) += NodalJointWidth[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE) += NodalMidPlaneLiquidPressure[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_DAMAGE) += NodalDamage[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_SLIP_TENDENCY) += NodalSlipTendency[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_AREA) += Area; rGeom[i].UnSetLock(); } @@ -311,7 +353,7 @@ void UPlSmallStrainInterfaceElement<3,6>::ExtrapolateGPValues (const std::vector //---------------------------------------------------------------------------------------- template< > -void UPlSmallStrainInterfaceElement<3,8>::ExtrapolateGPValues (const std::vector& JointWidthContainer) +void UPlSmallStrainInterfaceElement<3,8>::ExtrapolateGPValues (const ExtrapolationVariables& MyExtrapolationVariables) { array_1d DamageContainer; // 4 LobattoPoints @@ -325,14 +367,24 @@ void UPlSmallStrainInterfaceElement<3,8>::ExtrapolateGPValues (const std::vector const double& Area = rGeom.Area(); array_1d NodalJointWidth; - NodalJointWidth[0] = JointWidthContainer[0]*Area; - NodalJointWidth[1] = JointWidthContainer[1]*Area; - NodalJointWidth[2] = JointWidthContainer[2]*Area; - NodalJointWidth[3] = JointWidthContainer[3]*Area; - NodalJointWidth[4] = JointWidthContainer[0]*Area; - NodalJointWidth[5] = JointWidthContainer[1]*Area; - NodalJointWidth[6] = JointWidthContainer[2]*Area; - NodalJointWidth[7] = JointWidthContainer[3]*Area; + NodalJointWidth[0] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + NodalJointWidth[1] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[2] = MyExtrapolationVariables.JointWidthContainer[2]*Area; + NodalJointWidth[3] = MyExtrapolationVariables.JointWidthContainer[3]*Area; + NodalJointWidth[4] = MyExtrapolationVariables.JointWidthContainer[0]*Area; + NodalJointWidth[5] = MyExtrapolationVariables.JointWidthContainer[1]*Area; + NodalJointWidth[6] = MyExtrapolationVariables.JointWidthContainer[2]*Area; + NodalJointWidth[7] = MyExtrapolationVariables.JointWidthContainer[3]*Area; + + array_1d NodalMidPlaneLiquidPressure; + NodalMidPlaneLiquidPressure[0] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; + NodalMidPlaneLiquidPressure[1] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[2] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[2]*Area; + NodalMidPlaneLiquidPressure[3] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[3]*Area; + NodalMidPlaneLiquidPressure[4] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[0]*Area; + NodalMidPlaneLiquidPressure[5] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[1]*Area; + NodalMidPlaneLiquidPressure[6] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[2]*Area; + NodalMidPlaneLiquidPressure[7] = MyExtrapolationVariables.MidPlaneLiquidPressureContainer[3]*Area; array_1d NodalDamage; NodalDamage[0] = DamageContainer[0]*Area; @@ -344,11 +396,23 @@ void UPlSmallStrainInterfaceElement<3,8>::ExtrapolateGPValues (const std::vector NodalDamage[6] = DamageContainer[2]*Area; NodalDamage[7] = DamageContainer[3]*Area; + array_1d NodalSlipTendency; + NodalSlipTendency[0] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + NodalSlipTendency[1] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[2] = MyExtrapolationVariables.SlipTendencyContainer[2]*Area; + NodalSlipTendency[3] = MyExtrapolationVariables.SlipTendencyContainer[3]*Area; + NodalSlipTendency[4] = MyExtrapolationVariables.SlipTendencyContainer[0]*Area; + NodalSlipTendency[5] = MyExtrapolationVariables.SlipTendencyContainer[1]*Area; + NodalSlipTendency[6] = MyExtrapolationVariables.SlipTendencyContainer[2]*Area; + NodalSlipTendency[7] = MyExtrapolationVariables.SlipTendencyContainer[3]*Area; + for(unsigned int i = 0; i < 8; i++) //NumNodes { rGeom[i].SetLock(); rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_WIDTH) += NodalJointWidth[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE) += NodalMidPlaneLiquidPressure[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_DAMAGE) += NodalDamage[i]; + rGeom[i].FastGetSolutionStepValue(NODAL_SLIP_TENDENCY) += NodalSlipTendency[i]; rGeom[i].FastGetSolutionStepValue(NODAL_JOINT_AREA) += Area; rGeom[i].UnSetLock(); } @@ -414,6 +478,58 @@ void UPlSmallStrainInterfaceElement::CalculateOnIntegrationPoint this->InterpolateOutputDoubles(rValues,GPValues); } + else if(rVariable == MID_PLANE_LIQUID_PRESSURE) + { + // Obtain the geometry and the number of Gauss Points + const GeometryType& Geom = this->GetGeometry(); + const unsigned int NumGPoints = Geom.IntegrationPointsNumber( mThisIntegrationMethod ); + + // Obtain the shape functions + const Matrix& NContainer = Geom.ShapeFunctionsValues( mThisIntegrationMethod ); + + // Vector containing the results at Lobatto Points + std::vector GPValues(NumGPoints); + + // Obtain the values of the liquid pressure at each of the nodes + array_1d PressureVector; + for(unsigned int i=0; iGetIntegrationMethod() ); + if ( rValues.size() != OutputGPoints ) + rValues.resize( OutputGPoints ); + + this->InterpolateOutputDoubles(rValues,GPValues); + } + else if(rVariable == SLIP_TENDENCY) + { + //Variables computed on Lobatto points + const GeometryType& Geom = this->GetGeometry(); + const unsigned int NumGPoints = Geom.IntegrationPointsNumber( mThisIntegrationMethod ); + std::vector GPValues(NumGPoints); + + for ( unsigned int i = 0; i < NumGPoints; i++ ) { + GPValues[i] = mConstitutiveLawVector[i]->GetValue( rVariable, GPValues[i] ); + } + + //Printed on standard GiD + const unsigned int OutputGPoints = Geom.IntegrationPointsNumber( this->GetIntegrationMethod() ); + if ( rValues.size() != OutputGPoints ) + rValues.resize( OutputGPoints ); + + this->InterpolateOutputDoubles(rValues,GPValues); + } else { //Printed on standard GiD Gauss points diff --git a/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.hpp b/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.hpp index 9871f5a29bdb..b331cafb0b4e 100644 --- a/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.hpp +++ b/applications/PoromechanicsApplication/custom_elements/one-phase_flow/U_Pl_small_strain_interface_element.hpp @@ -154,6 +154,13 @@ class KRATOS_API(POROMECHANICS_APPLICATION) UPlSmallStrainInterfaceElement : pub array_1d PVector; }; + struct ExtrapolationVariables + { + std::vector JointWidthContainer; + std::vector MidPlaneLiquidPressureContainer; + std::vector SlipTendencyContainer; + }; + /// Member Variables std::vector mInitialGap; @@ -164,7 +171,7 @@ class KRATOS_API(POROMECHANICS_APPLICATION) UPlSmallStrainInterfaceElement : pub void CalculateInitialGap(const GeometryType& Geom); - void ExtrapolateGPValues (const std::vector& JointWidthContainer); + void ExtrapolateGPValues (const ExtrapolationVariables& MyExtrapolationVariables); void CalculateStiffnessMatrix( MatrixType& rStiffnessMatrix, const ProcessInfo& rCurrentProcessInfo ) override; diff --git a/applications/PoromechanicsApplication/custom_python/poromechanics_python_application.cpp b/applications/PoromechanicsApplication/custom_python/poromechanics_python_application.cpp index 6a9107327df7..742841b31efd 100644 --- a/applications/PoromechanicsApplication/custom_python/poromechanics_python_application.cpp +++ b/applications/PoromechanicsApplication/custom_python/poromechanics_python_application.cpp @@ -74,6 +74,9 @@ PYBIND11_MODULE(KratosPoromechanicsApplication, m) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, JOINT_WIDTH ) + KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, MID_PLANE_LIQUID_PRESSURE) + KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, SLIP_TENDENCY ) + KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_SMOOTHING ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_CAUCHY_STRESS_TENSOR ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, EFFECTIVE_STRESS_TENSOR ) @@ -82,6 +85,8 @@ PYBIND11_MODULE(KratosPoromechanicsApplication, m) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_JOINT_AREA ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_JOINT_WIDTH ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_JOINT_DAMAGE ) + KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_MID_PLANE_LIQUID_PRESSURE ) + KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, NODAL_SLIP_TENDENCY ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, SHEAR_FRACTURE_ENERGY ) KRATOS_REGISTER_IN_PYTHON_VARIABLE( m, BIOT_COEFFICIENT ) diff --git a/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_explicit_cd_scheme.hpp b/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_explicit_cd_scheme.hpp index bb36f13abeeb..3d5baeb78df4 100644 --- a/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_explicit_cd_scheme.hpp +++ b/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_explicit_cd_scheme.hpp @@ -648,6 +648,8 @@ class PoroExplicitCDScheme noalias(rNodalStress) = ZeroMatrix(3,3); itNode->FastGetSolutionStepValue(NODAL_JOINT_AREA) = 0.0; itNode->FastGetSolutionStepValue(NODAL_JOINT_WIDTH) = 0.0; + itNode->FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE) = 0.0; + itNode->FastGetSolutionStepValue(NODAL_SLIP_TENDENCY) = 0.0; itNode->FastGetSolutionStepValue(NODAL_JOINT_DAMAGE) = 0.0; } @@ -679,6 +681,10 @@ class PoroExplicitCDScheme const double InvNodalJointArea = 1.0/NodalJointArea; double& NodalJointWidth = itNode->FastGetSolutionStepValue(NODAL_JOINT_WIDTH); NodalJointWidth *= InvNodalJointArea; + double& NodalMidPlaneLiquidPressure = itNode->FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE); + NodalMidPlaneLiquidPressure *= InvNodalJointArea; + double& NodalSlipTendency = itNode->FastGetSolutionStepValue(NODAL_SLIP_TENDENCY); + NodalSlipTendency *= InvNodalJointArea; double& NodalJointDamage = itNode->FastGetSolutionStepValue(NODAL_JOINT_DAMAGE); NodalJointDamage *= InvNodalJointArea; } diff --git a/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_newmark_quasistatic_U_Pl_scheme.hpp b/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_newmark_quasistatic_U_Pl_scheme.hpp index 52e87fd424f6..d778611bdf8d 100644 --- a/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_newmark_quasistatic_U_Pl_scheme.hpp +++ b/applications/PoromechanicsApplication/custom_strategies/schemes/one-phase_flow/poro_newmark_quasistatic_U_Pl_scheme.hpp @@ -319,6 +319,8 @@ class PoroNewmarkQuasistaticUPlScheme : public Scheme noalias(rNodalStress) = ZeroMatrix(3,3); itNode->FastGetSolutionStepValue(NODAL_JOINT_AREA) = 0.0; itNode->FastGetSolutionStepValue(NODAL_JOINT_WIDTH) = 0.0; + itNode->FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE) = 0.0; + itNode->FastGetSolutionStepValue(NODAL_SLIP_TENDENCY) = 0.0; itNode->FastGetSolutionStepValue(NODAL_JOINT_DAMAGE) = 0.0; } @@ -350,6 +352,10 @@ class PoroNewmarkQuasistaticUPlScheme : public Scheme const double InvNodalJointArea = 1.0/NodalJointArea; double& NodalJointWidth = itNode->FastGetSolutionStepValue(NODAL_JOINT_WIDTH); NodalJointWidth *= InvNodalJointArea; + double& NodalMidPlaneLiquidPressure = itNode->FastGetSolutionStepValue(NODAL_MID_PLANE_LIQUID_PRESSURE); + NodalMidPlaneLiquidPressure *= InvNodalJointArea; + double& NodalSlipTendency = itNode->FastGetSolutionStepValue(NODAL_SLIP_TENDENCY); + NodalSlipTendency *= InvNodalJointArea; double& NodalJointDamage = itNode->FastGetSolutionStepValue(NODAL_JOINT_DAMAGE); NodalJointDamage *= InvNodalJointArea; } diff --git a/applications/PoromechanicsApplication/poromechanics_application.cpp b/applications/PoromechanicsApplication/poromechanics_application.cpp index ec05803a9ffc..c0641a3c871c 100644 --- a/applications/PoromechanicsApplication/poromechanics_application.cpp +++ b/applications/PoromechanicsApplication/poromechanics_application.cpp @@ -263,6 +263,8 @@ void KratosPoromechanicsApplication::Register() KRATOS_REGISTER_VARIABLE( INITIAL_JOINT_WIDTH ) KRATOS_REGISTER_VARIABLE( TRANSVERSAL_PERMEABILITY_COEFFICIENT ) + KRATOS_REGISTER_VARIABLE( MID_PLANE_LIQUID_PRESSURE ) + KRATOS_REGISTER_VARIABLE( SLIP_TENDENCY ) KRATOS_REGISTER_3D_VARIABLE_WITH_COMPONENTS( LIQUID_FLUX_VECTOR ) KRATOS_REGISTER_3D_VARIABLE_WITH_COMPONENTS( LOCAL_LIQUID_FLUX_VECTOR ) KRATOS_REGISTER_3D_VARIABLE_WITH_COMPONENTS( CONTACT_STRESS_VECTOR ) @@ -298,6 +300,8 @@ void KratosPoromechanicsApplication::Register() KRATOS_REGISTER_VARIABLE( NODAL_JOINT_AREA ) KRATOS_REGISTER_VARIABLE( NODAL_JOINT_WIDTH ) KRATOS_REGISTER_VARIABLE( NODAL_JOINT_DAMAGE ) + KRATOS_REGISTER_VARIABLE( NODAL_MID_PLANE_LIQUID_PRESSURE ) + KRATOS_REGISTER_VARIABLE( NODAL_SLIP_TENDENCY ) KRATOS_REGISTER_VARIABLE( SHEAR_FRACTURE_ENERGY ) diff --git a/applications/PoromechanicsApplication/poromechanics_application_variables.cpp b/applications/PoromechanicsApplication/poromechanics_application_variables.cpp index 64aa39d0a73e..76e63180d187 100644 --- a/applications/PoromechanicsApplication/poromechanics_application_variables.cpp +++ b/applications/PoromechanicsApplication/poromechanics_application_variables.cpp @@ -47,6 +47,8 @@ KRATOS_CREATE_VARIABLE( double, PERMEABILITY_ZX ) KRATOS_CREATE_VARIABLE( double, INITIAL_JOINT_WIDTH ) KRATOS_CREATE_VARIABLE( double, TRANSVERSAL_PERMEABILITY_COEFFICIENT ) +KRATOS_CREATE_VARIABLE( double, MID_PLANE_LIQUID_PRESSURE ) +KRATOS_CREATE_VARIABLE( double, SLIP_TENDENCY ) KRATOS_CREATE_3D_VARIABLE_WITH_COMPONENTS( LIQUID_FLUX_VECTOR ) KRATOS_CREATE_3D_VARIABLE_WITH_COMPONENTS( LOCAL_LIQUID_FLUX_VECTOR ) KRATOS_CREATE_3D_VARIABLE_WITH_COMPONENTS( CONTACT_STRESS_VECTOR ) @@ -92,6 +94,8 @@ KRATOS_CREATE_3D_VARIABLE_WITH_COMPONENTS( LIQUID_PRESSURE_GRADIENT ) KRATOS_CREATE_VARIABLE( double, NODAL_JOINT_AREA ) KRATOS_CREATE_VARIABLE( double, NODAL_JOINT_WIDTH ) KRATOS_CREATE_VARIABLE( double, NODAL_JOINT_DAMAGE ) +KRATOS_CREATE_VARIABLE( double, NODAL_MID_PLANE_LIQUID_PRESSURE ) +KRATOS_CREATE_VARIABLE( double, NODAL_SLIP_TENDENCY ) KRATOS_CREATE_VARIABLE( double, SHEAR_FRACTURE_ENERGY ) diff --git a/applications/PoromechanicsApplication/poromechanics_application_variables.h b/applications/PoromechanicsApplication/poromechanics_application_variables.h index ec1c216f6662..9041698c8b58 100644 --- a/applications/PoromechanicsApplication/poromechanics_application_variables.h +++ b/applications/PoromechanicsApplication/poromechanics_application_variables.h @@ -70,6 +70,8 @@ KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, COHESION KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, INITIAL_JOINT_WIDTH ) KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, TRANSVERSAL_PERMEABILITY_COEFFICIENT ) +KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, MID_PLANE_LIQUID_PRESSURE ) +KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, SLIP_TENDENCY ) KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( POROMECHANICS_APPLICATION, LIQUID_FLUX_VECTOR ) KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( POROMECHANICS_APPLICATION, LOCAL_LIQUID_FLUX_VECTOR ) KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( POROMECHANICS_APPLICATION, CONTACT_STRESS_VECTOR ) @@ -105,6 +107,8 @@ KRATOS_DEFINE_3D_APPLICATION_VARIABLE_WITH_COMPONENTS( POROMECHANICS_APPLICATION KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, NODAL_JOINT_AREA ) KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, NODAL_JOINT_WIDTH ) KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, NODAL_JOINT_DAMAGE ) +KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, NODAL_MID_PLANE_LIQUID_PRESSURE ) +KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, NODAL_SLIP_TENDENCY ) KRATOS_DEFINE_APPLICATION_VARIABLE( POROMECHANICS_APPLICATION, double, SHEAR_FRACTURE_ENERGY ) diff --git a/applications/PoromechanicsApplication/python_scripts/poromechanics_U_Pl_solver.py b/applications/PoromechanicsApplication/python_scripts/poromechanics_U_Pl_solver.py index 75c2ef48d109..895beb703649 100644 --- a/applications/PoromechanicsApplication/python_scripts/poromechanics_U_Pl_solver.py +++ b/applications/PoromechanicsApplication/python_scripts/poromechanics_U_Pl_solver.py @@ -141,6 +141,8 @@ def AddVariables(self): self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_JOINT_AREA) self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_JOINT_WIDTH) self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_JOINT_DAMAGE) + self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_MID_PLANE_LIQUID_PRESSURE) + self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_SLIP_TENDENCY) self.main_model_part.AddNodalSolutionStepVariable(KratosMultiphysics.NODAL_AREA) self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.NODAL_EFFECTIVE_STRESS_TENSOR) self.main_model_part.AddNodalSolutionStepVariable(KratosPoro.INITIAL_STRESS_TENSOR) diff --git a/docs/pages/index.md b/docs/pages/index.md index 728a31ec8b8d..1cb77a9e1354 100644 --- a/docs/pages/index.md +++ b/docs/pages/index.md @@ -9,27 +9,6 @@ summary:

-[release-image]: https://img.shields.io/badge/release-9.3-green.svg?style=flat -[releases]: https://github.com/KratosMultiphysics/Kratos/releases - -[license-image]: https://img.shields.io/badge/license-BSD-green.svg?style=flat -[license]: https://github.com/KratosMultiphysics/Kratos/blob/master/kratos/license.txt - -[c++-image]: https://img.shields.io/badge/C++-17-blue.svg?style=flat&logo=c%2B%2B -[c++standard]: https://isocpp.org/std/the-standard - -[Nightly-Build]: https://github.com/KratosMultiphysics/Kratos/workflows/Nightly%20Build/badge.svg -[Nightly-link]: https://github.com/KratosMultiphysics/Kratos/actions?query=workflow%3A%22Nightly+Build%22 - -[DOI-image]: https://zenodo.org/badge/DOI/10.5281/zenodo.3234644.svg -[DOI]: https://doi.org/10.5281/zenodo.3234644 - -[stars-image]: https://img.shields.io/github/stars/KratosMultiphysics/Kratos?label=Stars&logo=github -[stars]: https://github.com/KratosMultiphysics/Kratos/stargazers - -[twitter-image]: https://img.shields.io/twitter/follow/kratosmultiphys.svg?label=Follow&style=social -[twitter]: https://twitter.com/kratosmultiphys - _KRATOS Multiphysics_ ("Kratos") is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface. More in [Overview](https://github.com/KratosMultiphysics/Kratos/wiki/Overview) **Kratos** is **free** under BSD-4 [license](https://github.com/KratosMultiphysics/Kratos/wiki/Licence) and can be used even in comercial softwares as it is. Many of its main applications are also free and BSD-4 licensed but each derived application can have its own propietary license. @@ -164,6 +143,10 @@ Looking forward to seeing your logo here! # How to cite Kratos? Please, use the following references when citing Kratos in your work. -- Dadvand, P., Rossi, R. & Oñate, E. An Object-oriented Environment for Developing Finite Element Codes for Multi-disciplinary Applications. Arch Computat Methods Eng 17, 253–297 (2010). -- Dadvand, P., Rossi, R., Gil, M., Martorell, X., Cotela, J., Juanpere, E., Idelsohn, S., Oñate, E. (2013). Migration of a generic multi-physics framework to HPC environments. Computers & Fluids. 80. 301–309. 10.1016/j.compfluid.2012.02.004. -- Vicente Mataix Ferrándiz, Philipp Bucher, Rubén Zorrilla, Riccardo Rossi, Jordi Cotela, Alejandro Cornejo Velázquez, Miguel Angel Celigueta, Josep Maria, Tobias Teschemacher, Carlos Roig, Miguel Maso, Guillermo Casas, Suneth Warnakulasuriya, Marc Núñez, Pooyan Dadvand, Salva Latorre, Ignasi de Pouplana, Joaquín Irazábal González, Ferran Arrufat, … Javi Gárate. (2022). KratosMultiphysics/Kratos: Release 9.2 (v9.2). Zenodo. +- [Dadvand, P., Rossi, R. & Oñate, E. An Object-oriented Environment for Developing Finite Element Codes for Multi-disciplinary Applications. Arch Computat Methods Eng 17, 253–297 (2010). https://doi.org/10.1007/s11831-010-9045-2](https://doi.org/10.1007/s11831-010-9045-2) +- [Dadvand, P., Rossi, R., Gil, M., Martorell, X., Cotela, J., Juanpere, E., Idelsohn, S., Oñate, E. (2013). Migration of a generic multi-physics framework to HPC environments. Computers & Fluids. 80. 301–309. 10.1016/j.compfluid.2012.02.004.](10.1016/j.compfluid.2012.02.004) +- [Vicente Mataix Ferrándiz, Philipp Bucher, Rubén Zorrilla, Suneth Warnakulasuriya, Riccardo Rossi, Alejandro Cornejo, jcotela, Carlos Roig, Josep Maria, tteschemacher, Miguel Masó, Guillermo Casas, Marc Núñez, Pooyan Dadvand, Salva Latorre, Ignasi de Pouplana, Joaquín Irazábal González, AFranci, Ferran Arrufat, riccardotosi, Aditya Ghantasala, Klaus Bernd Sautter, Peter Wilson, dbaumgaertner, Bodhinanda Chandra, Armin Geiser, Inigo Lopez, lluís, jgonzalezusua, Javi Gárate. (2024). KratosMultiphysics/Kratos: Release 9.5 (v9.5). Zenodo. https://doi.org/10.5281/zenodo.3234644](https://zenodo.org/records/6926179) + +# Activity + +![Git Repository Activity](https://repobeats.axiom.co/api/embed/925787aa734f5f16ad8524017c7feb20d1a0f317.svg) diff --git a/kratos/containers/pointer_hash_map_set.h b/kratos/containers/pointer_hash_map_set.h index 75bf4b2104c1..0539ef102d3f 100644 --- a/kratos/containers/pointer_hash_map_set.h +++ b/kratos/containers/pointer_hash_map_set.h @@ -2,25 +2,19 @@ // ' / __| _` | __| _ \ __| // . \ | ( | | ( |\__ ` // _|\_\_| \__,_|\__|\___/ ____/ -// Multi-Physics +// Multi-Physics // -// License: BSD License -// Kratos default license: kratos/license.txt +// License: BSD License +// Kratos default license: kratos/license.txt // // Main authors: Pooyan Dadvand -// +// // - - -#if !defined(KRATOS_POINTER_HASH_MAP_SET_H_INCLUDED ) -#define KRATOS_POINTER_HASH_MAP_SET_H_INCLUDED - - +#pragma once // System includes - // External includes #include #include @@ -31,32 +25,17 @@ #include "includes/serializer.h" #include "containers/set_identity_function.h" -namespace Kratos -{ -///@name Kratos Globals -///@{ - -///@} -///@name Type Definitions -///@{ - -///@} -///@name Enum's -///@{ -///@} -///@name Functions -///@{ +namespace Kratos { -///@} ///@name Kratos Classes ///@{ /// PointerHashMapSet is a hash implemenetation of the PointerVectorSet. -/** This container is like a set but is built over a hash map in order - to allow the key to be a part of the value. It is important to mention - that the value is not constant and if the key inside the value changed - outside results in inconsistence condition. +/** This container is like a set but is built over a hash map in order + to allow the key to be a part of the value. It is important to mention + that the value is not constant and if the key inside the value changed + outside results in inconsistence condition. This Container does not free the memory by itself and relies on using of counted pointers or manual @@ -86,7 +65,7 @@ class PointerHashMapSet final typedef TPointerType pointer_type; typedef TDataType& reference; typedef const TDataType& const_reference; - // typedef std::unordered_map ContainerType; + // typedef std::unordered_map ContainerType; typedef std::unordered_map::type, TPointerType, THashType> ContainerType; typedef typename ContainerType::size_type size_type; @@ -94,66 +73,66 @@ class PointerHashMapSet final typedef typename ContainerType::const_iterator ptr_const_iterator; typedef typename ContainerType::difference_type difference_type; - ///@} + ///@} private: - ///@name Nested clases - ///@{ - class iterator_adaptor - { - ptr_iterator map_iterator; - public: + ///@name Nested clases + ///@{ + class iterator_adaptor + { + ptr_iterator map_iterator; + public: using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = data_type; using pointer = data_type*; using reference = data_type&; - - iterator_adaptor(ptr_iterator it) :map_iterator(it) {} - iterator_adaptor(const iterator_adaptor& it) : map_iterator(it.map_iterator) {} - iterator_adaptor& operator++() { map_iterator++; return *this; } - iterator_adaptor operator++(int) { iterator_adaptor tmp(*this); operator++(); return tmp; } - bool operator==(const iterator_adaptor& rhs) const { return map_iterator == rhs.map_iterator; } - bool operator!=(const iterator_adaptor& rhs) const { return map_iterator != rhs.map_iterator; } - data_type& operator*() const { return *(map_iterator->second); } - pointer_type operator->() const { return map_iterator->second; } - ptr_iterator& base() { return map_iterator; } - ptr_iterator const& base() const { return map_iterator; } - }; - - class const_iterator_adaptor - { - ptr_const_iterator map_iterator; - public: + + iterator_adaptor(ptr_iterator it) :map_iterator(it) {} + iterator_adaptor(const iterator_adaptor& it) : map_iterator(it.map_iterator) {} + iterator_adaptor& operator++() { map_iterator++; return *this; } + iterator_adaptor operator++(int) { iterator_adaptor tmp(*this); operator++(); return tmp; } + bool operator==(const iterator_adaptor& rhs) const { return map_iterator == rhs.map_iterator; } + bool operator!=(const iterator_adaptor& rhs) const { return map_iterator != rhs.map_iterator; } + data_type& operator*() const { return *(map_iterator->second); } + pointer_type operator->() const { return map_iterator->second; } + ptr_iterator& base() { return map_iterator; } + ptr_iterator const& base() const { return map_iterator; } + }; + + class const_iterator_adaptor + { + ptr_const_iterator map_iterator; + public: using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = data_type; using pointer = data_type*; using reference = data_type&; - const_iterator_adaptor(ptr_const_iterator it) :map_iterator(it) {} - const_iterator_adaptor(const const_iterator_adaptor& it) : map_iterator(it.map_iterator) {} - const_iterator_adaptor& operator++() { map_iterator++; return *this; } - const_iterator_adaptor operator++(int) { const_iterator_adaptor tmp(*this); operator++(); return tmp; } - bool operator==(const const_iterator_adaptor& rhs) const { return map_iterator == rhs.map_iterator; } - bool operator!=(const const_iterator_adaptor& rhs) const { return map_iterator != rhs.map_iterator; } - data_type const& operator*() const { return *(map_iterator->second); } - pointer_type operator->() const { return map_iterator->second; } - ptr_const_iterator& base() { return map_iterator; } - ptr_const_iterator const& base() const { return map_iterator; } - }; + const_iterator_adaptor(ptr_const_iterator it) :map_iterator(it) {} + const_iterator_adaptor(const const_iterator_adaptor& it) : map_iterator(it.map_iterator) {} + const_iterator_adaptor& operator++() { map_iterator++; return *this; } + const_iterator_adaptor operator++(int) { const_iterator_adaptor tmp(*this); operator++(); return tmp; } + bool operator==(const const_iterator_adaptor& rhs) const { return map_iterator == rhs.map_iterator; } + bool operator!=(const const_iterator_adaptor& rhs) const { return map_iterator != rhs.map_iterator; } + data_type const& operator*() const { return *(map_iterator->second); } + pointer_type operator->() const { return map_iterator->second; } + ptr_const_iterator& base() { return map_iterator; } + ptr_const_iterator const& base() const { return map_iterator; } + }; - ///@} + ///@} public: - ///@name Type Definitions - ///@{ + ///@name Type Definitions + ///@{ - typedef iterator_adaptor iterator; - typedef const_iterator_adaptor const_iterator; + typedef iterator_adaptor iterator; + typedef const_iterator_adaptor const_iterator; - ///@} + ///@} ///@name Life Cycle ///@{ @@ -187,30 +166,30 @@ class PointerHashMapSet final { mData = rOther.mData; - return *this; + return *this; } TDataType& operator[](const key_type& Key) { - KRATOS_DEBUG_ERROR_IF(mData.find(Key) == mData.end()) << "The key: " << Key << " is not available in the map" << std::endl; - return *(mData.find(Key)->second); + KRATOS_DEBUG_ERROR_IF(mData.find(Key) == mData.end()) << "The key: " << Key << " is not available in the map" << std::endl; + return *(mData.find(Key)->second); } pointer_type& operator()(const key_type& Key) { - KRATOS_DEBUG_ERROR_IF(mData.find(Key) == mData.end()) << "The key: " << Key << " is not available in the map" << std::endl; - return mData.find(Key)->second; - } + KRATOS_DEBUG_ERROR_IF(mData.find(Key) == mData.end()) << "The key: " << Key << " is not available in the map" << std::endl; + return mData.find(Key)->second; + } bool operator==( const PointerHashMapSet& r ) const // nothrow { return (mData == r.mData); } - bool operator!=(const PointerHashMapSet& r) const // nothrow - { - return (mData != r.mData); - } + bool operator!=(const PointerHashMapSet& r) const // nothrow + { + return (mData != r.mData); + } ///@} @@ -250,42 +229,11 @@ class PointerHashMapSet final return mData.end(); } - reference front() /* nothrow */ - { - //assert( !empty() ); - return *(mData.front().second); - } - const_reference front() const /* nothrow */ - { - //assert( !empty() ); - return *(mData.front().second); - } - reference back() /* nothrow */ - { - //assert( !empty() ); - return *(mData.back().second); - } - const_reference back() const /* nothrow */ - { - //assert( !empty() ); - return *(mData.back().second); - } - size_type size() const { return mData.size(); } - //size_type max_size() const - //{ - // return mData.max_size(); - //} - - //key_compare key_comp() const - //{ - // return TCompareType(); - //} - void swap(PointerHashMapSet& rOther) { mData.swap(rOther.mData); @@ -294,8 +242,8 @@ class PointerHashMapSet final template iterator insert(const TOtherDataType& rData) { - TDataType* p_new_data = new TDataType(rData); - return mData.insert(ContainerType::value_type(TGetKeyOf(rData), p_new_data)); + TDataType* p_new_data = new TDataType(rData); + return mData.insert(ContainerType::value_type(TGetKeyOf(rData), p_new_data)); } iterator insert(TPointerType pData) @@ -305,7 +253,7 @@ class PointerHashMapSet final std::pair result = mData.insert(item); // TODO: I should enable this after adding the KRATOS_ERROR to define.h. Pooyan. //if(result.second != true) - // KRATOS_ERROR << "Error in adding the new item" << std::endl + // KRATOS_ERROR << "Error in adding the new item" << std::endl return result.first; } @@ -317,17 +265,17 @@ class PointerHashMapSet final } - iterator erase(iterator pos) - { - return mData.erase(pos.base()); - } + iterator erase(iterator pos) + { + return mData.erase(pos.base()); + } - size_type erase(key_type const& Key) - { - return mData.erase(Key); - } + size_type erase(key_type const& Key) + { + return mData.erase(Key); + } - iterator erase( iterator first, iterator last ) + iterator erase( iterator first, iterator last ) { return mData.erase( first.base(), last.base() ); } @@ -344,8 +292,8 @@ class PointerHashMapSet final const_iterator find(const key_type& Key) const { - return mData.find(Key); - } + return mData.find(Key); + } size_type count(const key_type& Key) { @@ -361,7 +309,7 @@ class PointerHashMapSet final return mData.capacity(); } - + ///@} ///@name Access ///@{ @@ -378,8 +326,6 @@ class PointerHashMapSet final return mData; } - - ///@} ///@name Inquiry ///@{ @@ -417,68 +363,14 @@ class PointerHashMapSet final } - ///@} - ///@name Friends - ///@{ - - - ///@} - -protected: - ///@name Protected static Member Variables - ///@{ - - - ///@} - ///@name Protected member Variables - ///@{ - - - ///@} - ///@name Protected Operators - ///@{ - - - ///@} - ///@name Protected Operations - ///@{ - - - ///@} - ///@name Protected Access - ///@{ - - - ///@} - ///@name Protected Inquiry - ///@{ - - - ///@} - ///@name Protected LifeCycle - ///@{ - - ///@} private: - - - ///@name Static Member Variables - ///@{ - - - ///@} ///@name Member Variables ///@{ ContainerType mData; - ///@} - ///@name Private Operators - ///@{ - - ///@} ///@name Private Operations ///@{ @@ -512,7 +404,7 @@ class PointerHashMapSet final rSerializer.save("size", size); - for (ptr_const_iterator i = ptr_begin(); i != ptr_end(); i++) + for (ptr_const_iterator i = ptr_begin(); i != ptr_end(); i++) rSerializer.save("E", i->second); } @@ -522,55 +414,23 @@ class PointerHashMapSet final rSerializer.load("size", size); - for (size_type i = 0; i < size; i++) - { - pointer_type p = nullptr;// new TDataType; - rSerializer.load("E", p); - insert(p); - } + for (size_type i = 0; i < size; i++) + { + pointer_type p = nullptr;// new TDataType; + rSerializer.load("E", p); + insert(p); + } } ///@} - ///@name Private Access - ///@{ - - - ///@} - ///@name Private Inquiry - ///@{ - - - ///@} - ///@name Un accessible methods - ///@{ - - - ///@} - }; // Class PointerHashMapSet -///@} - -///@name Type Definitions -///@{ - - ///@} ///@name Input and output ///@{ -/// input stream function -//template -//inline std::istream& operator >> (std::istream& rIStream, -// PointerHashMapSet& rThis); - /// output stream function template -inline std::ostream& operator << (std::ostream& rOStream, - const PointerHashMapSet& rThis) +std::ostream& operator << (std::ostream& rOStream, + const PointerHashMapSet& rThis) { rThis.PrintInfo(rOStream); rOStream << std::endl; @@ -591,5 +451,3 @@ inline std::ostream& operator << (std::ostream& rOStream, } // namespace Kratos. - -#endif // KRATOS_POINTER_HASH_MAP_SET_H_INCLUDED defined diff --git a/kratos/includes/kratos_application.h b/kratos/includes/kratos_application.h index 7cc7004c339b..fc5949f069da 100644 --- a/kratos/includes/kratos_application.h +++ b/kratos/includes/kratos_application.h @@ -76,6 +76,7 @@ #include "modeler/serial_model_part_combinator_modeler.h" #include "modeler/combine_model_part_modeler.h" #include "modeler/connectivity_preserve_modeler.h" +#include "modeler/voxel_mesh_generator_modeler.h" namespace Kratos { ///@name Kratos Classes @@ -495,6 +496,7 @@ class KRATOS_API(KRATOS_CORE) KratosApplication { const SerialModelPartCombinatorModeler mSerialModelPartCombinatorModeler; const CombineModelPartModeler mCombineModelPartModeler; const ConnectivityPreserveModeler mConnectivityPreserveModeler; + const VoxelMeshGeneratorModeler mVoxelMeshGeneratorModeler; // Base constitutive law definition const ConstitutiveLaw mConstitutiveLaw; diff --git a/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.cpp b/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.cpp new file mode 100644 index 000000000000..35ab6e9e2162 --- /dev/null +++ b/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.cpp @@ -0,0 +1,99 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_and_intersect_with_cells_in_touch.h" + +namespace Kratos { + +ColorAndIntersectWithCellsInTouch::ColorAndIntersectWithCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorAndIntersectWithCellsInTouch::Apply() const +{ + auto parameters = GetParameters(); + auto& r_model_part = GetModelPart(parameters["model_part_name"].GetString()); + + const int inside_color = parameters["color"].GetInt(); + const std::string input_entities = parameters["input_entities"].GetString(); + + auto& r_skin_intersections = GetIntersections(inside_color); + + if (input_entities == "elements") { + for(auto& r_geometrical_object : r_model_part.Elements()) { + auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometryAndComputeIntersection(r_geometry, inside_color, r_skin_intersections); + } + } else if(input_entities == "conditions") { + for(auto& r_geometrical_object : r_model_part.Conditions()) { + auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometryAndComputeIntersection(r_geometry, inside_color, r_skin_intersections); + } + } else if(input_entities == "geometries") { + for(auto& r_geometry : r_model_part.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometryAndComputeIntersection(r_geometry, inside_color, r_skin_intersections); + } + } else { + KRATOS_ERROR << "The input_entities " << parameters["input_entities"] << " is not supported. The supported input_entities are elements and conditions" << std::endl; + } +} + + +Parameters ColorAndIntersectWithCellsInTouch::GetDefaultParameters() const { + return Parameters(R"({ + "type" : "Undefined_coloring_type", + "model_part_name": "Undefined", + "color": -1, + "cell_color": -1, + "input_entities": "elements", + "outside_color": 0 + })"); +} + + +void ColorAndIntersectWithCellsInTouch::ApplyColorToCellsInTouchWithGeometryAndComputeIntersection( + const Element::GeometryType& rGeometry, + int InsideColor, + Internals::SkinIntersection& rSkinIntersection) const +{ + auto& r_colors = GetMeshColors(); + + auto p_work_geometry = rSkinIntersection.ConvertToWorkGeometry(rGeometry); + array_1d min_position(3,0); + array_1d max_position(3,0); + r_colors.CalculateOuterMinMaxNodePositions(rGeometry, min_position, max_position); + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + Point cell_min_point = r_colors.GetPoint(i,j,k); + Point cell_max_point = r_colors.GetPoint(i+1,j+1,k+1); + if(rGeometry.HasIntersection(cell_min_point,cell_max_point)){ + r_colors.GetElementalColor(i,j,k) = InsideColor; + + rSkinIntersection.ComputeCutInsideCell(p_work_geometry, cell_min_point, cell_max_point, i, j, k); + } + } + } + } +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.h b/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.h new file mode 100644 index 000000000000..8851a9a6122a --- /dev/null +++ b/kratos/modeler/coloring/color_and_intersect_with_cells_in_touch.h @@ -0,0 +1,45 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorAndIntersectWithCellsInTouch: public VoxelMesherColoring { + +public: + ColorAndIntersectWithCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorAndIntersectWithCellsInTouch() override = default; + + void Apply() const override; + + Parameters GetDefaultParameters() const override; + +private: + + void ApplyColorToCellsInTouchWithGeometryAndComputeIntersection( + const Geometry& rGeometry, + int InsideColor, + Internals::SkinIntersection& rSkinIntersection) const; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cell_faces.cpp b/kratos/modeler/coloring/color_cell_faces.cpp new file mode 100644 index 000000000000..043a1119d57c --- /dev/null +++ b/kratos/modeler/coloring/color_cell_faces.cpp @@ -0,0 +1,67 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_cell_faces.h" + +namespace Kratos { + +ColorCellFaces::ColorCellFaces(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorCellFaces::Apply() const +{ + auto parameters = GetParameters(); + auto& r_model_part = GetModelPart(parameters["model_part_name"].GetString()); + CartesianMeshColors& r_colors = GetMeshColors(); + + const int outside_color = parameters["outside_color"].GetInt(); + const int interface_color = parameters["color"].GetInt(); + const int cell_color = parameters["cell_color"].GetInt(); + const std::string input_entities = parameters["input_entities"].GetString(); + + array_1d< std::size_t, 3 > min_ray_position{0, 0, 0}; + array_1d< std::size_t, 3 > max_ray_position{0, 0, 0}; + + r_colors.CalculateMinMaxCenterOfElementPositions(r_model_part.Nodes(), min_ray_position, max_ray_position); + r_colors.InitializeRays(min_ray_position, max_ray_position, "center_of_elements"); + + if(input_entities == "elements") { + for(auto& element : r_model_part.Elements()) { + Element::GeometryType& r_geometry = element.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } else if(input_entities == "conditions") { + for(auto& condition : r_model_part.Conditions()) { + auto& r_geometry = condition.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } else if(input_entities == "geometries") { + for(auto& r_geometry : r_model_part.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } + + r_colors.CalculateElementalFaceColors(min_ray_position, max_ray_position, interface_color, outside_color, cell_color); +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cell_faces.h b/kratos/modeler/coloring/color_cell_faces.h new file mode 100644 index 000000000000..dfd150568130 --- /dev/null +++ b/kratos/modeler/coloring/color_cell_faces.h @@ -0,0 +1,35 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorCellFaces: public VoxelMesherColoring { + +public: + ColorCellFaces(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorCellFaces() override = default; + + void Apply() const override; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cell_faces_between_colors.cpp b/kratos/modeler/coloring/color_cell_faces_between_colors.cpp new file mode 100644 index 000000000000..e0bcd3dae321 --- /dev/null +++ b/kratos/modeler/coloring/color_cell_faces_between_colors.cpp @@ -0,0 +1,38 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_cell_faces_between_colors.h" + +namespace Kratos { + +ColorCellFacesBetweenColors::ColorCellFacesBetweenColors(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorCellFacesBetweenColors::Apply() const +{ + Parameters parameters = GetParameters(); + const int outside_color = parameters["outside_color"].GetInt(); + const int interface_color = parameters["color"].GetInt(); + const int cell_color = parameters["cell_color"].GetInt(); + + GetMeshColors().CalculateElementalFaceColorsBetweenColors(interface_color, outside_color, cell_color); +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cell_faces_between_colors.h b/kratos/modeler/coloring/color_cell_faces_between_colors.h new file mode 100644 index 000000000000..ecad0796b6f4 --- /dev/null +++ b/kratos/modeler/coloring/color_cell_faces_between_colors.h @@ -0,0 +1,34 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorCellFacesBetweenColors: public VoxelMesherColoring { + +public: + ColorCellFacesBetweenColors(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorCellFacesBetweenColors() override = default; + + void Apply() const override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_in_touch.cpp b/kratos/modeler/coloring/color_cells_in_touch.cpp new file mode 100644 index 000000000000..65604c44ae8e --- /dev/null +++ b/kratos/modeler/coloring/color_cells_in_touch.cpp @@ -0,0 +1,83 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_cells_in_touch.h" + +namespace Kratos { + +ColorCellsInTouch::ColorCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorCellsInTouch::Apply() const +{ + auto parameters = GetParameters(); + auto& r_model_part = GetModelPart(parameters["model_part_name"].GetString()); + + const int inside_color = parameters["color"].GetInt(); + const int outside_color = parameters["outside_color"].GetInt(); + const std::string input_entities = parameters["input_entities"].GetString(); + + if (input_entities == "elements") { + for(auto& r_geometrical_object : r_model_part.Elements()) { + const auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometry(r_geometry, inside_color, outside_color); + } + } else if(input_entities == "conditions") { + for(auto& r_geometrical_object : r_model_part.Conditions()) { + const auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometry(r_geometry, inside_color, outside_color); + } + } else if(input_entities == "geometries") { + for(const auto& r_geometry : r_model_part.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToCellsInTouchWithGeometry(r_geometry, inside_color, outside_color); + } + } else { + KRATOS_ERROR << "The input_entities " << parameters["input_entities"] << " is not supported. The supported input_entities are elements and conditions" << std::endl; + } +} + + +void ColorCellsInTouch::ApplyColorToCellsInTouchWithGeometry( + const Geometry& rGeometry, + int InsideColor, + int OutsideColor) const +{ + auto& r_colors = GetMeshColors(); + + array_1d min_position(3,0); + array_1d max_position(3,0); + r_colors.CalculateOuterMinMaxNodePositions(rGeometry, min_position, max_position); + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + Point cell_min_point = r_colors.GetPoint(i,j,k); + Point cell_max_point = r_colors.GetPoint(i+1,j+1,k+1); + if(rGeometry.HasIntersection(cell_min_point,cell_max_point)){ + r_colors.GetElementalColor(i,j,k) = InsideColor; + } + } + } + } +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_in_touch.h b/kratos/modeler/coloring/color_cells_in_touch.h new file mode 100644 index 000000000000..77c9a13cf63e --- /dev/null +++ b/kratos/modeler/coloring/color_cells_in_touch.h @@ -0,0 +1,43 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorCellsInTouch: public VoxelMesherColoring { + +public: + ColorCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorCellsInTouch() override = default; + + void Apply() const override; + +private: + + void ApplyColorToCellsInTouchWithGeometry( + const Geometry& rGeometry, + int InsideColor, + int OutsideColor) const; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.cpp b/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.cpp new file mode 100644 index 000000000000..7baf3fb2a933 --- /dev/null +++ b/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.cpp @@ -0,0 +1,61 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "includes/dem_variables.h" +#include "color_cells_with_center_in_sphere_around_nodes.h" + +namespace Kratos { + +ColorCellsWithCenterInSphereArounNodes::ColorCellsWithCenterInSphereArounNodes(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorCellsWithCenterInSphereArounNodes::Apply() const +{ + const ModelPart& r_input_model_part = GetInputModelPart(); + CartesianMeshColors& r_colors = GetMeshColors(); + Parameters parameters = GetParameters(); + const int color = parameters["color"].GetInt(); + + for(const auto& i_node : r_input_model_part.Nodes()){ + array_1d< std::size_t, 3 > min_position; + array_1d< std::size_t, 3 > max_position; + double radius = i_node.GetSolutionStepValue(RADIUS); + double radius2 = radius * radius; // storing radius**2 to avoid sqrt in comparison + + for(int i = 0; i < 3; i++ ) { + min_position[i] = r_colors.CalculateCenterOfElementPosition(i_node[i] - radius, i); + max_position[i] = r_colors.CalculateCenterOfElementPosition(i_node[i] + radius, i) + 1; + } + + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + Point cell_center = r_colors.GetCenterOfElement(i,j,k); + array_1d distance_vector = i_node.Coordinates() - cell_center.Coordinates(); + if(inner_prod(distance_vector, distance_vector) < radius2){ + r_colors.GetElementalColor(i,j,k) = color; + } + } + } + } + } +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.h b/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.h new file mode 100644 index 000000000000..3d491a697e2f --- /dev/null +++ b/kratos/modeler/coloring/color_cells_with_center_in_sphere_around_nodes.h @@ -0,0 +1,35 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorCellsWithCenterInSphereArounNodes: public VoxelMesherColoring { + +public: + ColorCellsWithCenterInSphereArounNodes(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorCellsWithCenterInSphereArounNodes() override = default; + + void Apply() const override; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_with_inside_center.cpp b/kratos/modeler/coloring/color_cells_with_inside_center.cpp new file mode 100644 index 000000000000..b08bf74e147c --- /dev/null +++ b/kratos/modeler/coloring/color_cells_with_inside_center.cpp @@ -0,0 +1,68 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_cells_with_inside_center.h" + +namespace Kratos { + +ColorCellsWithInsideCenter::ColorCellsWithInsideCenter(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorCellsWithInsideCenter::Apply() const +{ + auto parameters = GetParameters(); + auto& r_model_part = GetModelPart(parameters["model_part_name"].GetString()); + auto& r_colors = GetMeshColors(); + const int inside_color = parameters["color"].GetInt(); + const int outside_color = parameters["outside_color"].GetInt(); + const std::string input_entities = parameters["input_entities"].GetString(); + + array_1d< std::size_t, 3 > min_ray_position{0, 0, 0}; + array_1d< std::size_t, 3 > max_ray_position{0, 0, 0}; + + r_colors.CalculateMinMaxCenterOfElementPositions(r_model_part.Nodes(), min_ray_position, max_ray_position); + + r_colors.InitializeRays(min_ray_position, max_ray_position, "center_of_elements"); + + if(input_entities == "elements") { + for(auto& r_element : r_model_part.Elements()) { + Element::GeometryType& r_geometry = r_element.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } else if(input_entities == "conditions"){ + for(auto& r_condition : r_model_part.Conditions()) { + Condition::GeometryType& r_geometry = r_condition.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } else if(input_entities == "geometries"){ + for(auto& r_geometry : r_model_part.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + r_colors.AddGeometry(r_geometry, false); + } + } else{ + KRATOS_ERROR << "The input_entities " << parameters["input_entities"] << " is not supported. The supported input_entities are geometries, elements and conditions" << std::endl; + } + + r_colors.CalculateElementalRayColors(min_ray_position, max_ray_position, inside_color, outside_color); +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_cells_with_inside_center.h b/kratos/modeler/coloring/color_cells_with_inside_center.h new file mode 100644 index 000000000000..ae5475a349a0 --- /dev/null +++ b/kratos/modeler/coloring/color_cells_with_inside_center.h @@ -0,0 +1,34 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorCellsWithInsideCenter: public VoxelMesherColoring { + +public: + ColorCellsWithInsideCenter(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorCellsWithInsideCenter() override = default; + + void Apply() const override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_connected_cells_in_touch.cpp b/kratos/modeler/coloring/color_connected_cells_in_touch.cpp new file mode 100644 index 000000000000..ec078a7df769 --- /dev/null +++ b/kratos/modeler/coloring/color_connected_cells_in_touch.cpp @@ -0,0 +1,139 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "color_connected_cells_in_touch.h" + +namespace Kratos { + +ColorConnectedCellsInTouch::ColorConnectedCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorConnectedCellsInTouch::Apply() const +{ + Parameters parameters = GetParameters(); + ModelPart& r_skin_model_part = GetModelPart(parameters["model_part_name"].GetString()); + + const int inside_color = parameters["color"].GetInt(); + const int cell_color = parameters["cell_color"].GetInt(); + const std::string input_entities = parameters["input_entities"].GetString(); + + if(input_entities == "elements") { + for(auto& r_geometrical_object : r_skin_model_part.Elements()) { + auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToConnectedCellsInTouchWithGeometry(r_geometry, inside_color, cell_color); + } + } else if(input_entities == "conditions") { + for(auto& r_geometrical_object : r_skin_model_part.Conditions()) { + auto& r_geometry = r_geometrical_object.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToConnectedCellsInTouchWithGeometry(r_geometry, inside_color, cell_color); + } + } else if(input_entities == "geometries") { + for(auto& r_geometry : r_skin_model_part.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + ApplyColorToConnectedCellsInTouchWithGeometry(r_geometry, inside_color, cell_color); + } + } else{ + KRATOS_ERROR << "The input_entities " << input_entities << " is not supported. The supported input_entities are elements and conditions" << std::endl; + } +} + + +void ColorConnectedCellsInTouch::ApplyColorToConnectedCellsInTouchWithGeometry( + const Geometry& rGeometry, + const int InsideColor, + const int CellColor + ) const +{ + array_1d min_position(3,0); + array_1d max_position(3,0); + CartesianMeshColors& r_colors = GetMeshColors(); + r_colors.CalculateOuterMinMaxNodePositions(rGeometry, min_position, max_position); + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + const int cell_color = std::lround(r_colors.GetElementalColor(i,j,k)); + if (cell_color == CellColor) { + Point cell_min_point = r_colors.GetPoint(i,j,k); + Point cell_max_point = r_colors.GetPoint(i+1,j+1,k+1); + if(rGeometry.HasIntersection(cell_min_point,cell_max_point)){ + ColorConnectedCellsToThisCell(i,j,k,InsideColor, CellColor, r_colors); + } + } + } + } + } +} + + +void ColorConnectedCellsInTouch::ColorConnectedCellsToThisCell( + const std::size_t I, + const std::size_t J, + const std::size_t K, + const int InsideColor, + const int CellColor, + CartesianMeshColors& rColors) const +{ + std::vector> stack; + stack.emplace_back(I,J,K); + const std::size_t i_size = rColors.GetNodalCoordinates(0).size(); + const std::size_t j_size = rColors.GetNodalCoordinates(1).size(); + const std::size_t k_size = rColors.GetNodalCoordinates(2).size(); + while (!stack.empty()) { + auto& indices = stack.back(); + const auto i = std::get<0>(indices); + const auto j = std::get<1>(indices); + const auto k = std::get<2>(indices); + stack.pop_back(); + rColors.GetElementalColor(i,j,k) = InsideColor; + if(i > 0){ + if(std::lround(rColors.GetElementalColor(i-1, j, k)) == CellColor){ + stack.emplace_back(i-1, j, k); + } + } + if(j > 0){ + if(std::lround(rColors.GetElementalColor(i, j-1, k)) == CellColor){ + stack.emplace_back(i, j-1, k); + } + } + if(k > 0){ + if(std::lround(rColors.GetElementalColor(i, j, k-1)) == CellColor){ + stack.emplace_back(i, j, k-1); + } + } + if(i+1 < i_size){ + if(std::lround(rColors.GetElementalColor(i+1, j, k)) == CellColor){ + stack.emplace_back(i+1, j, k); + } + } + if(j+1 < j_size){ + if(std::lround(rColors.GetElementalColor(i, j+1, k)) == CellColor){ + stack.emplace_back(i, j+1, k); + } + } + if(k+1 < k_size){ + if(std::lround(rColors.GetElementalColor(i, j, k+1)) == CellColor){ + stack.emplace_back(i, j, k+1); + } + } + } +} + +} diff --git a/kratos/modeler/coloring/color_connected_cells_in_touch.h b/kratos/modeler/coloring/color_connected_cells_in_touch.h new file mode 100644 index 000000000000..04d944a56cfc --- /dev/null +++ b/kratos/modeler/coloring/color_connected_cells_in_touch.h @@ -0,0 +1,52 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorConnectedCellsInTouch: public VoxelMesherColoring { + +public: + ColorConnectedCellsInTouch(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorConnectedCellsInTouch() override = default; + + void Apply() const override; + +private: + + void ApplyColorToConnectedCellsInTouchWithGeometry( + const Geometry& rGeometry, + const int InsideColor, + const int CellColor + ) const; + + void ColorConnectedCellsToThisCell( + const std::size_t I, + const std::size_t J, + const std::size_t K, + const int InsideColor, + const int CellColor, + CartesianMeshColors& rColors) const; + +}; + +} diff --git a/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.cpp b/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.cpp new file mode 100644 index 000000000000..61061d1ec294 --- /dev/null +++ b/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.cpp @@ -0,0 +1,87 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry.h" +#include "color_outer_faces_of_cells_with_colors.h" + +namespace Kratos { + +ColorOuterFacesOfCellsWithColors::ColorOuterFacesOfCellsWithColors(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + VoxelMesherColoring(rModeler, ColoringParameters) +{} + + +void ColorOuterFacesOfCellsWithColors::Apply() const +{ + Parameters parameters = GetParameters(); + CartesianMeshColors& r_colors = GetMeshColors(); + + const int interface_color = parameters["color"].GetInt(); + const int cell_color = parameters["cell_color"].GetInt(); + + array_1d number_of_cells; + for(int i = 0 ; i < 3 ; i++){ + number_of_cells[i] = GetKeyPlanes(i).size() - 1; + } + + array_1d cell_indices; + for (cell_indices[2] = 0; cell_indices[2] < number_of_cells[2]; cell_indices[2]++) { + for (cell_indices[1] = 0; cell_indices[1] < number_of_cells[1]; cell_indices[1]++) { + for (cell_indices[0] = 0; cell_indices[0] < number_of_cells[0]; cell_indices[0]++) { + if(std::lround(r_colors.GetElementalColor(cell_indices[0],cell_indices[1],cell_indices[2])) == cell_color){ + ApplyColorIfOuterFace(interface_color, cell_color, cell_indices); + } + } + } + } +} + + +void ColorOuterFacesOfCellsWithColors::ApplyColorIfOuterFace( + const int InterfaceColor, + const int CellColor, + const array_1d& rCellIndices) const +{ + CartesianMeshColors& r_colors = GetMeshColors(); + auto& r_faces_color = r_colors.GetElementalFaceColor(rCellIndices[0],rCellIndices[1],rCellIndices[2]); + for(int i_direction = 0 ; i_direction < 3 ; i_direction++){ + const auto& r_key_planes = GetKeyPlanes(i_direction); + if(rCellIndices[i_direction] == 0) { // It is the first cell and has outer face + r_faces_color[i_direction] = InterfaceColor; + } else { + array_1d neighbor_cell_indices = rCellIndices; + neighbor_cell_indices[i_direction]--; + const int neigh_cell_color = std::lround(r_colors.GetElementalColor(neighbor_cell_indices[0],neighbor_cell_indices[1],neighbor_cell_indices[2])); + if(neigh_cell_color != CellColor){ + r_faces_color[i_direction] = InterfaceColor; + } + } + if(rCellIndices[i_direction] == (r_key_planes.size() - 2)) { // It is the last cell has outer face + r_faces_color[i_direction + 3] = InterfaceColor; + } else { + array_1d neighbor_cell_indices = rCellIndices; + neighbor_cell_indices[i_direction]++; + const int neigh_cell_color = std::lround(r_colors.GetElementalColor(neighbor_cell_indices[0],neighbor_cell_indices[1],neighbor_cell_indices[2])); + if(neigh_cell_color != CellColor){ + r_faces_color[i_direction + 3] = InterfaceColor; + } + } + } +} + + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.h b/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.h new file mode 100644 index 000000000000..73c5deb99cf0 --- /dev/null +++ b/kratos/modeler/coloring/color_outer_faces_of_cells_with_colors.h @@ -0,0 +1,42 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +class ColorOuterFacesOfCellsWithColors: public VoxelMesherColoring { + +public: + ColorOuterFacesOfCellsWithColors(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + ~ColorOuterFacesOfCellsWithColors() override = default; + + void Apply() const override; + +private: + + void ApplyColorIfOuterFace( + const int InterfaceColor, + const int CellColor, + const array_1d& rCellIndices) const; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/voxel_mesher_coloring.cpp b/kratos/modeler/coloring/voxel_mesher_coloring.cpp new file mode 100644 index 000000000000..5ae1f7b9ee3f --- /dev/null +++ b/kratos/modeler/coloring/voxel_mesher_coloring.cpp @@ -0,0 +1,85 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "includes/checks.h" + +#include "voxel_mesher_coloring.h" +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos { + +VoxelMesherColoring::VoxelMesherColoring(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters): + mrModeler(rModeler), + mParameters(ColoringParameters) +{} + + +void VoxelMesherColoring::ValidateParameters() +{ + mParameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); +} + + +Parameters VoxelMesherColoring::GetParameters() const +{ + return mParameters; +} + + +Parameters VoxelMesherColoring::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "Undefined_coloring_type", + "model_part_name": "Undefined", + "color": -1, + "cell_color": -1, + "input_entities": "elements", + "outside_color" : 0 + })"); +} + + +void VoxelMesherColoring::CheckGeometryType(const GeometryData::KratosGeometryType &rType) const { + KRATOS_ERROR_IF_NOT(rType == GeometryData::KratosGeometryType::Kratos_Triangle3D3) << " Input entities must be of type Triangle3D3" << std::endl; +} + + +ModelPart& VoxelMesherColoring::GetModelPart(const std::string& rName) const { + return mrModeler.mpModel->GetModelPart(rName); +} + + +const ModelPart& VoxelMesherColoring::GetInputModelPart() const { + return *(mrModeler.mpInputModelPart); +} + +VoxelMesherColoring::CartesianMeshColors& VoxelMesherColoring::GetMeshColors() const { + return mrModeler.mColors; +} + + +VoxelMesherColoring::SkinIntersection& VoxelMesherColoring::GetIntersections(int Color) const +{ + return mrModeler.GetIntersections(Color); +} + + +const std::vector& VoxelMesherColoring::GetKeyPlanes(std::size_t Direction) const { + return mrModeler.mKeyPlanes[Direction]; +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/voxel_mesher_coloring.h b/kratos/modeler/coloring/voxel_mesher_coloring.h new file mode 100644 index 000000000000..7838de42b813 --- /dev/null +++ b/kratos/modeler/coloring/voxel_mesher_coloring.h @@ -0,0 +1,70 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "geometries/geometry_data.h" +#include "includes/kratos_parameters.h" + +#include "modeler/voxel_mesh_generator_modeler.h" +#include "modeler/internals/cartesian_mesh_colors.h" +#include "modeler/internals/skin_intersection.h" + +namespace Kratos { + +class KRATOS_API(KRATOS_CORE) VoxelMesherColoring { + + VoxelMeshGeneratorModeler& mrModeler; + Parameters mParameters; + +public: + + KRATOS_CLASS_POINTER_DEFINITION(VoxelMesherColoring); + + using CartesianMeshColors = Internals::CartesianMeshColors; + using SkinIntersection = Internals::SkinIntersection; + + VoxelMesherColoring(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringParameters); + + virtual ~VoxelMesherColoring() = default; + + virtual void ValidateParameters(); + + virtual void Apply() const = 0; + +protected: + + Parameters GetParameters() const; + + virtual Parameters GetDefaultParameters() const; + + void CheckGeometryType(const GeometryData::KratosGeometryType &rType) const; + + // internal interface to VoxelMeshGeneratorModeler + + ModelPart& GetModelPart(const std::string& rName) const; + + const ModelPart& GetInputModelPart() const; + + CartesianMeshColors& GetMeshColors() const; + + SkinIntersection& GetIntersections(int Color) const; + + const std::vector& GetKeyPlanes(std::size_t Direction) const; +}; + +} diff --git a/kratos/modeler/coloring/voxel_mesher_coloring_factory.cpp b/kratos/modeler/coloring/voxel_mesher_coloring_factory.cpp new file mode 100644 index 000000000000..a4f8b1927b94 --- /dev/null +++ b/kratos/modeler/coloring/voxel_mesher_coloring_factory.cpp @@ -0,0 +1,46 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_coloring_factory.h" + +#include "modeler/coloring/voxel_mesher_coloring.h" +#include "modeler/coloring/color_cells_with_inside_center.h" +#include "modeler/coloring/color_cells_in_touch.h" +#include "modeler/coloring/color_and_intersect_with_cells_in_touch.h" +#include "modeler/coloring/color_cell_faces.h" +#include "modeler/coloring/color_cell_faces_between_colors.h" +#include "modeler/coloring/color_outer_faces_of_cells_with_colors.h" +#include "modeler/coloring/color_cells_with_center_in_sphere_around_nodes.h" +#include "modeler/coloring/color_connected_cells_in_touch.h" + +namespace Kratos { + +template class KratosComponents; + +void RegisterVoxelMesherColoring() +{ + VoxelMesherColoringFactory::Register("cells_with_inside_center"); + VoxelMesherColoringFactory::Register("cells_in_touch"); + VoxelMesherColoringFactory::Register("intersect_with_cells_in_touch"); + VoxelMesherColoringFactory::Register("cells_faces"); + VoxelMesherColoringFactory::Register("cells_faces_between_colors"); + VoxelMesherColoringFactory::Register("outer_faces_of_cells_with_color"); + VoxelMesherColoringFactory::Register("cells_with_center_in_sphere_arround_nodes"); + VoxelMesherColoringFactory::Register("connected_cells_in_touch"); +} + +} \ No newline at end of file diff --git a/kratos/modeler/coloring/voxel_mesher_coloring_factory.h b/kratos/modeler/coloring/voxel_mesher_coloring_factory.h new file mode 100644 index 000000000000..b4b851d5ffbd --- /dev/null +++ b/kratos/modeler/coloring/voxel_mesher_coloring_factory.h @@ -0,0 +1,31 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "modeler/internals/voxel_mesher_component_factory.h" +#include "voxel_mesher_coloring.h" + +namespace Kratos { + +using VoxelMesherColoringFactory = VoxelMesherComponentFactory; + +KRATOS_API_EXTERN template class KRATOS_API(KRATOS_CORE) KratosComponents; + +void RegisterVoxelMesherColoring(); + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_conditions_with_face_color.cpp b/kratos/modeler/entity_generation/generate_conditions_with_face_color.cpp new file mode 100644 index 000000000000..d575ded9665e --- /dev/null +++ b/kratos/modeler/entity_generation/generate_conditions_with_face_color.cpp @@ -0,0 +1,78 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "generate_conditions_with_face_color.h" + +namespace Kratos { + +Parameters GenerateConditionsWithFaceColor::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "conditions_with_face_color", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "SurfaceCondition3D4N" + })"); +} + +void GenerateConditionsWithFaceColor::Generate(ModelPart& rModelPart, Parameters parameters) +{ + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t condition_id = GetStartConditionId(); + + const int inside_color = parameters["color"].GetInt(); + std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + const std::size_t x_offset[24]={0,0,0,0, 0,1,1,0, 0,0,1,1, 1,1,1,1, 0,0,1,1, 0,1,1,0}; + const std::size_t y_offset[24]={0,0,1,1, 0,0,0,0, 0,1,1,0, 0,1,1,0, 1,1,1,1, 0,0,1,1}; + const std::size_t z_offset[24]={0,1,1,0, 0,0,1,1, 0,0,0,0, 0,0,1,1, 0,1,1,0, 1,1,1,1}; + + array_1d number_of_cells = GetNumberOfCells(); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ConditionsContainerType new_conditions; + auto& r_prototype_condition = KratosComponents::Get( + parameters["generated_entity"].GetString()); + + Element::NodesArrayType face_nodes(4); + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + const auto& r_faces_color = r_colors.GetElementalFaceColor(i,j,k); + for(std::size_t i_face = 0; i_face < 6; i_face++){ + if(std::lround(r_faces_color[i_face]) == inside_color){ + std::size_t base_index=i_face*4; + face_nodes(0) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index] , j+y_offset[base_index] , k+z_offset[base_index] ); + face_nodes(1) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+1], j+y_offset[base_index+1] , k+z_offset[base_index+1]); + face_nodes(2) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+2], j+y_offset[base_index+2] , k+z_offset[base_index+2]); + face_nodes(3) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+3], j+y_offset[base_index+3] , k+z_offset[base_index+3]); + //create the new condition + Condition::Pointer p_condition = r_prototype_condition.Create(condition_id++, face_nodes, p_properties); + new_conditions.push_back(p_condition); + } + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddConditions(new_conditions.begin(), new_conditions.end()); +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_conditions_with_face_color.h b/kratos/modeler/entity_generation/generate_conditions_with_face_color.h new file mode 100644 index 000000000000..06599a58071c --- /dev/null +++ b/kratos/modeler/entity_generation/generate_conditions_with_face_color.h @@ -0,0 +1,37 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateConditionsWithFaceColor: public VoxelMesherEntityGeneration { +public: + GenerateConditionsWithFaceColor(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateConditionsWithFaceColor() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_elements_with_cell_color.cpp b/kratos/modeler/entity_generation/generate_elements_with_cell_color.cpp new file mode 100644 index 000000000000..19491c664902 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_elements_with_cell_color.cpp @@ -0,0 +1,70 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "generate_elements_with_cell_color.h" + +namespace Kratos { + +Parameters GenerateElementsWithCellColor::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "elements_with_cell_color", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "Element3D8N" + })"); +} + +void GenerateElementsWithCellColor::Generate(ModelPart& rModelPart, Parameters parameters) +{ + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t element_id = GetStartElementId(); + + const int inside_color = parameters["color"].GetInt(); + std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + array_1d number_of_cells = GetNumberOfCells(); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ElementsContainerType new_elements; + + auto& r_prototype_element = KratosComponents::Get( + parameters["generated_entity"].GetString()); + + Element::NodesArrayType cell_nodes(8); + + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + if(std::lround(r_colors.GetElementalColor(i,j,k)) == inside_color){ + this->GetLinearCellNodes(cell_nodes, rModelPart, new_nodes, i, j, k); + + //create the new element + Element::Pointer p_element = r_prototype_element.Create(element_id++, cell_nodes, p_properties); + new_elements.push_back(p_element); + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddElements(new_elements.begin(), new_elements.end()); +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_elements_with_cell_color.h b/kratos/modeler/entity_generation/generate_elements_with_cell_color.h new file mode 100644 index 000000000000..29f65311ae76 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_elements_with_cell_color.h @@ -0,0 +1,37 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateElementsWithCellColor: public VoxelMesherEntityGeneration { +public: + GenerateElementsWithCellColor(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateElementsWithCellColor() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.cpp b/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.cpp new file mode 100644 index 000000000000..cef1172f4f8d --- /dev/null +++ b/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.cpp @@ -0,0 +1,72 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "generate_quadratic_elements_with_cell_color.h" + +namespace Kratos { + +Parameters GenerateQuadraticElementsWithCellColor::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "quadratic_elements_with_cell_color", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "Element3D27N" + })"); +} + +void GenerateQuadraticElementsWithCellColor::Generate(ModelPart& rModelPart, Parameters parameters) +{ + InitializeQuadraticData(); + + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t element_id = GetStartElementId(); + + const int inside_color = parameters["color"].GetInt(); + std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + array_1d number_of_cells = GetNumberOfCells(); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ElementsContainerType new_elements; + + auto& r_prototype_element = KratosComponents::Get( + parameters["generated_entity"].GetString()); + + Element::NodesArrayType cell_nodes(27); + + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + if(std::lround(r_colors.GetElementalColor(i,j,k)) == inside_color){ + this->GetQuadraticCellNodes(cell_nodes, rModelPart, new_nodes, i, j, k); + + //create the new element + Element::Pointer p_element = r_prototype_element.Create(element_id++, cell_nodes, p_properties); + new_elements.push_back(p_element); + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddElements(new_elements.begin(), new_elements.end()); +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.h b/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.h new file mode 100644 index 000000000000..6ebcb80cb236 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_quadratic_elements_with_cell_color.h @@ -0,0 +1,37 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateQuadraticElementsWithCellColor: public VoxelMesherEntityGeneration { +public: + GenerateQuadraticElementsWithCellColor(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateQuadraticElementsWithCellColor() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.cpp b/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.cpp new file mode 100644 index 000000000000..4922644afbd4 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.cpp @@ -0,0 +1,162 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "generate_stl_intersection_with_cells.h" + +namespace Kratos { + +Parameters GenerateStlIntersectionWithCells::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "generate_stl_intersection_with_cells", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "Element3D3N", + "input_entities": "elements", + "input_model_part_name": "" + })"); +} + +void GenerateStlIntersectionWithCells::Generate(ModelPart& rModelPart, Parameters parameters) +{ + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t element_id = GetStartElementId(); + + const int inside_color = parameters["color"].GetInt(); + std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + const std::string input_model_part_name = parameters["input_model_part_name"].GetString(); + if (input_model_part_name != "") { + const std::string input_entities = parameters["input_entities"].GetString(); + GenerateIntersection(GetModelPart(input_model_part_name), input_entities, inside_color); + } + + KRATOS_ERROR_IF_NOT(IntersectionsGenerated(inside_color)) << + "Intersections for color " << inside_color << " must be computed in advance to generate STL." << std::endl; + + auto& r_prototype_element = KratosComponents::Get( + parameters["generated_entity"].GetString()); + const SkinIntersection& r_intersections = GetIntersections(inside_color); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ElementsContainerType new_elements; + + array_1d number_of_cells = GetNumberOfCells(); + + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + if(std::lround(r_colors.GetElementalColor(i,j,k)) == inside_color){ + const auto& r_geometries = r_intersections.CutGeometriesInCell(i, j, k); + // Note: this is a STL-like mesh for output, the nodes are not unique + auto cut_nodes = GenerateCutGeometryNodes(rModelPart, r_geometries); + + for (auto i_node = cut_nodes.ptr_begin(); i_node != cut_nodes.ptr_end(); i_node += 3) { + auto geom = Kratos::make_shared>(*i_node, *(i_node+1), *(i_node+2)); + new_elements.push_back( + r_prototype_element.Create(element_id++, geom, p_properties)); + + } + + for (auto iter = cut_nodes.ptr_begin(); iter != cut_nodes.ptr_end(); ++iter) { + new_nodes.push_back(*iter); + } + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddElements(new_elements.begin(), new_elements.end()); +} + +PointerVector GenerateStlIntersectionWithCells::GenerateCutGeometryNodes( + ModelPart& rTheCutModelPart, + const std::vector& rCutGeometries) +{ + PointerVector nodes; + nodes.reserve(3*rCutGeometries.size()); + for (auto i_geom = rCutGeometries.begin(); i_geom < rCutGeometries.end(); ++i_geom) { + for (auto& r_point: **i_geom) { + nodes.push_back(GenerateNode(rTheCutModelPart, r_point)); + } + } + + return nodes; +} + + +void GenerateStlIntersectionWithCells::CheckGeometryType(const GeometryData::KratosGeometryType &rType) const { + KRATOS_ERROR_IF_NOT(rType == GeometryData::KratosGeometryType::Kratos_Triangle3D3) << + " Input entities must be of type Triangle3D3" << std::endl; +} + + +void GenerateStlIntersectionWithCells::GenerateIntersection(const ModelPart& rReferenceModelPart, const std::string& rInputEntities, int Color) { + const CartesianMeshColors& r_colors = GetMeshColors(); + SkinIntersection& r_skin_intersection = GetIntersections(Color); + + if (rInputEntities == "elements") { + for (const auto& r_elem: rReferenceModelPart.Elements()) { + const auto& r_geometry = r_elem.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + GenerateIntersection(r_geometry, Color, r_colors, r_skin_intersection); + } + } else if (rInputEntities == "conditions") { + for (const auto& r_cond: rReferenceModelPart.Conditions()) { + const auto& r_geometry = r_cond.GetGeometry(); + CheckGeometryType(r_geometry.GetGeometryType()); + GenerateIntersection(r_geometry, Color, r_colors, r_skin_intersection); + } + } else if (rInputEntities == "geometries") { + for(auto& r_geometry : rReferenceModelPart.Geometries()) { + CheckGeometryType(r_geometry.GetGeometryType()); + GenerateIntersection(r_geometry, Color, r_colors, r_skin_intersection); + } + } else { + KRATOS_ERROR << "The input_entities " << rInputEntities << " is not supported. The supported input_entities are elements and conditions" << std::endl; + } +} + + +void GenerateStlIntersectionWithCells::GenerateIntersection( + const Geometry& rGeometry, + int Color, + const CartesianMeshColors& rMeshColors, + SkinIntersection& rSkinIntersection) +{ + auto p_work_geometry = rSkinIntersection.ConvertToWorkGeometry(rGeometry); + array_1d min_position(3,0); + array_1d max_position(3,0); + rMeshColors.CalculateOuterMinMaxNodePositions(rGeometry, min_position, max_position); + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + Point cell_min_point = rMeshColors.GetPoint(i,j,k); + Point cell_max_point = rMeshColors.GetPoint(i+1,j+1,k+1); + if(rGeometry.HasIntersection(cell_min_point,cell_max_point)){ + rSkinIntersection.ComputeCutInsideCell(p_work_geometry, cell_min_point, cell_max_point, i, j, k); + } + } + } + } + +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.h b/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.h new file mode 100644 index 000000000000..a5b89a423626 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_stl_intersection_with_cells.h @@ -0,0 +1,57 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateStlIntersectionWithCells: public VoxelMesherEntityGeneration { +public: + using WorkGeometryType = Internals::SkinIntersection::SplitGeometryType; + + GenerateStlIntersectionWithCells(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateStlIntersectionWithCells() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; + +private: + + PointerVector GenerateCutGeometryNodes( + ModelPart& rTheCutModelPart, + const std::vector& rCutGeometries + ); + + void CheckGeometryType(const GeometryData::KratosGeometryType &rType) const; + + void GenerateIntersection(const ModelPart& rReferenceModelPart, const std::string& rInputEntities, int Color); + + void GenerateIntersection( + const Geometry& rGeometry, + int Color, + const CartesianMeshColors& rMeshColors, + SkinIntersection& rSkinIntersection + ); +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.cpp b/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.cpp new file mode 100644 index 000000000000..f3cf3a68f242 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.cpp @@ -0,0 +1,98 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "geometries/tetrahedra_3d_4.h" +#include "generate_tetrahedral_elements_with_cell_color.h" + +namespace Kratos { + +Parameters GenerateTetrahedralElementsWithCellColor::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "tetrahedral_elements_with_cell_color", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "Element3D4N" + })"); +} + +void GenerateTetrahedralElementsWithCellColor::Generate(ModelPart& rModelPart, Parameters parameters) +{ + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t element_id = GetStartElementId(); + + const int inside_color = parameters["color"].GetInt(); + const std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + auto& r_prototype_element = KratosComponents::Get( + parameters["generated_entity"].GetString()); + + array_1d number_of_cells = GetNumberOfCells(); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ElementsContainerType new_elements; + + Element::NodesArrayType cell_nodes(8); + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + if(std::lround(r_colors.GetElementalColor(i,j,k)) == inside_color){ + GetLinearCellNodes(cell_nodes, rModelPart, new_nodes, i, j, k); + CreateTetrahedraInCell(new_elements, cell_nodes, element_id, p_properties, r_prototype_element); + element_id += 6; + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddElements(new_elements.begin(), new_elements.end()); +} + +void GenerateTetrahedralElementsWithCellColor::CreateTetrahedraInCell( + ModelPart::ElementsContainerType& rElements, + Element::NodesArrayType& rCellNodes, + const std::size_t StartId, + Properties::Pointer& pProperties, + const Element& rPrototype) +{ + constexpr std::size_t nodes_per_tet = 4; + constexpr std::size_t tets_per_cell = 6; + using ConnectivityList = std::array, tets_per_cell>; + static constexpr ConnectivityList local_connectivities {{ { 0,3,6,2 }, + { 3,6,7,0 }, + { 4,7,6,0 }, + { 0,4,5,6 }, + { 0,1,2,6 }, + { 1,5,6,0 } }}; + + for(std::size_t i = 0; i < tets_per_cell; i++) { + const auto & connectivty = local_connectivities[i]; + + auto geom = Kratos::make_shared>( + rCellNodes(connectivty[0]), + rCellNodes(connectivty[1]), + rCellNodes(connectivty[2]), + rCellNodes(connectivty[3])); + + rElements.push_back(rPrototype.Create(StartId+i, geom, pProperties)); + } +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.h b/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.h new file mode 100644 index 000000000000..0abf8fff5b4a --- /dev/null +++ b/kratos/modeler/entity_generation/generate_tetrahedral_elements_with_cell_color.h @@ -0,0 +1,47 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateTetrahedralElementsWithCellColor: public VoxelMesherEntityGeneration { +public: + GenerateTetrahedralElementsWithCellColor(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateTetrahedralElementsWithCellColor() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; + +private: + + void CreateTetrahedraInCell( + ModelPart::ElementsContainerType& rElements, + Element::NodesArrayType& rCellNodes, + const std::size_t StartId, + Properties::Pointer& pProperties, + const Element& rPrototype + ); +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.cpp b/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.cpp new file mode 100644 index 000000000000..d91d323d7779 --- /dev/null +++ b/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.cpp @@ -0,0 +1,84 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "generate_triangular_conditions_with_face_color.h" + +namespace Kratos { + +Parameters GenerateTriangularConditionsWithFaceColor::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "triangular_conditions_with_face_color", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "SurfaceCondition3D3N" + })"); +} + +void GenerateTriangularConditionsWithFaceColor::Generate(ModelPart& rModelPart, Parameters parameters) +{ + const CartesianMeshColors& r_colors = GetMeshColors(); + std::size_t condition_id = GetStartConditionId(); + + const int inside_color = parameters["color"].GetInt(); + const std::size_t properties_id = parameters["properties_id"].GetInt(); + Properties::Pointer p_properties = CreateAndGetProperty(rModelPart, properties_id); + + const std::size_t x_offset[24]={0,0,0,0, 0,1,1,0, 0,0,1,1, 1,1,1,1, 0,0,1,1, 0,1,1,0}; + const std::size_t y_offset[24]={0,0,1,1, 0,0,0,0, 0,1,1,0, 0,1,1,0, 1,1,1,1, 0,0,1,1}; + const std::size_t z_offset[24]={0,1,1,0, 0,0,1,1, 0,0,0,0, 0,0,1,1, 0,1,1,0, 1,1,1,1}; + + array_1d number_of_cells = GetNumberOfCells(); + + ModelPart::NodesContainerType new_nodes; + ModelPart::ConditionsContainerType new_conditions; + auto& r_prototype_condition = KratosComponents::Get( + parameters["generated_entity"].GetString()); + + Element::NodesArrayType face_nodes_1(3); + Element::NodesArrayType face_nodes_2(3); + for (std::size_t k = 0; k < number_of_cells[2]; k++) { + for (std::size_t j = 0; j < number_of_cells[1]; j++) { + for (std::size_t i = 0; i < number_of_cells[0]; i++) { + auto& r_faces_color = r_colors.GetElementalFaceColor(i,j,k); + for(std::size_t i_face = 0; i_face < 6; i_face++){ + if(std::lround(r_faces_color[i_face]) == inside_color){ + std::size_t base_index=i_face*4; + face_nodes_1(0) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index] , j+y_offset[base_index] , k+z_offset[base_index] ); + face_nodes_1(1) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+1], j+y_offset[base_index+1] , k+z_offset[base_index+1]); + face_nodes_1(2) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+2], j+y_offset[base_index+2] , k+z_offset[base_index+2]); + + face_nodes_2(0) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index] , j+y_offset[base_index] , k+z_offset[base_index] ); + face_nodes_2(1) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+2], j+y_offset[base_index+2] , k+z_offset[base_index+2]); + face_nodes_2(2) = GenerateOrRetrieveNode(rModelPart, new_nodes, i+x_offset[base_index+3], j+y_offset[base_index+3] , k+z_offset[base_index+3]); + //create the new conditions + Condition::Pointer p_condition_1 = r_prototype_condition.Create(condition_id++, face_nodes_1, p_properties); + new_conditions.push_back(p_condition_1); + Condition::Pointer p_condition_2 = r_prototype_condition.Create(condition_id++, face_nodes_2, p_properties); + new_conditions.push_back(p_condition_2); + } + } + } + } + } + + AddNodesToModelPart(rModelPart, new_nodes); + rModelPart.AddConditions(new_conditions.begin(), new_conditions.end()); +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.h b/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.h new file mode 100644 index 000000000000..041478cc13dd --- /dev/null +++ b/kratos/modeler/entity_generation/generate_triangular_conditions_with_face_color.h @@ -0,0 +1,37 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +class GenerateTriangularConditionsWithFaceColor: public VoxelMesherEntityGeneration { +public: + GenerateTriangularConditionsWithFaceColor(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherEntityGeneration(rModeler, GenerationParameters) + {} + + ~GenerateTriangularConditionsWithFaceColor() override = default; + + Parameters GetDefaultParameters() const override; + + void Generate(ModelPart& rModelPart, Parameters parameters) override; +}; + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/voxel_mesher_entity_generation.cpp b/kratos/modeler/entity_generation/voxel_mesher_entity_generation.cpp new file mode 100644 index 000000000000..19a0a409cf62 --- /dev/null +++ b/kratos/modeler/entity_generation/voxel_mesher_entity_generation.cpp @@ -0,0 +1,246 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "utilities/model_part_utils.h" + +#include "voxel_mesher_entity_generation.h" + +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos { + +VoxelMesherEntityGeneration::VoxelMesherEntityGeneration(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + mrModeler(rModeler), + mParameters(GenerationParameters) +{} + + +void VoxelMesherEntityGeneration::ValidateParameters() +{ + mParameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); +} + + +void VoxelMesherEntityGeneration::Generate() { + std::string model_part_name = mParameters["model_part_name"].GetString(); + ModelPart& r_model_part = CreateAndGetModelPart(model_part_name); + SetStartIds(r_model_part); + + Generate(r_model_part, mParameters); +} + + +Parameters VoxelMesherEntityGeneration::GetParameters() const +{ + return mParameters; +} + + +Parameters VoxelMesherEntityGeneration::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "Undefined_entity_generation_type", + "model_part_name": "Undefined", + "color": -1, + "properties_id": 1, + "generated_entity": "Undefined" + })"); +} + + +ModelPart& VoxelMesherEntityGeneration::GetModelPart(const std::string& rName) const { + return mrModeler.mpModel->GetModelPart(rName); +} + + +ModelPart& VoxelMesherEntityGeneration::CreateAndGetModelPart(std::string const& rFullName) const +{ + return mrModeler.CreateAndGetModelPart(rFullName); +} + + +Properties::Pointer VoxelMesherEntityGeneration::CreateAndGetProperty(ModelPart& rModelPart, std::size_t PropertyId) const +{ + if(!rModelPart.RecursivelyHasProperties(PropertyId)){ + rModelPart.CreateNewProperties(PropertyId); + } + return rModelPart.pGetProperties(PropertyId); +} + + +const VoxelMesherEntityGeneration::CartesianMeshColors& VoxelMesherEntityGeneration::GetMeshColors() const +{ + return mrModeler.mColors; +} + + +const array_1d& VoxelMesherEntityGeneration::GetNumberOfDivisions() const { + return mrModeler.mMeshingData.GetNumberOfDivisions(); +} + + +const VoxelMesherEntityGeneration::SkinIntersection& VoxelMesherEntityGeneration::GetIntersections(int Color) const { + return mrModeler.GetIntersections(Color); +} + + +VoxelMesherEntityGeneration::SkinIntersection& VoxelMesherEntityGeneration::GetIntersections(int Color) { + return mrModeler.GetIntersections(Color); +} + + +bool VoxelMesherEntityGeneration::IntersectionsGenerated(int Color) const { + return mrModeler.IntersectionsGenerated(Color); +} + + +void VoxelMesherEntityGeneration::AddNodesToModelPart(ModelPart& rModelPart, ModelPart::NodesContainerType& rNewNodes) const +{ + rNewNodes.Unique(); + ModelPartUtils::AddNodesFromOrderedContainer(rModelPart, rNewNodes.begin(), rNewNodes.end()); +} + + +void VoxelMesherEntityGeneration::SetStartIds(ModelPart& rModelPart) +{ + mrModeler.SetStartIds(rModelPart); +} + + +std::size_t VoxelMesherEntityGeneration::GetStartElementId() const +{ + return mrModeler.mStartElementId; +} + + +std::size_t VoxelMesherEntityGeneration::GetStartConditionId() const +{ + return mrModeler.mStartConditionId; +} + +array_1d VoxelMesherEntityGeneration::GetNumberOfCells() const +{ + array_1d number_of_cells; + for(int i = 0 ; i < 3 ; i++){ + number_of_cells[i] = mrModeler.mKeyPlanes[i].size() - 1; + } + return number_of_cells; +} + + +Node::Pointer VoxelMesherEntityGeneration::GenerateOrRetrieveNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K) +{ + return mrModeler.GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I, J, K); +} + + +Node::Pointer VoxelMesherEntityGeneration::GenerateOrRetrieveQuadraticNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K) +{ + return mrModeler.GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, I, J, K); +} + + +Node::Pointer VoxelMesherEntityGeneration::GenerateNode(ModelPart& rModelPart, const Point& rCoordintates) +{ + return mrModeler.GenerateNode(rModelPart, rCoordintates); +} + + +void VoxelMesherEntityGeneration::GetLinearCellNodes( + Element::NodesArrayType& rCellNodes, + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K) +{ + rCellNodes(0) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I , J , K); + rCellNodes(1) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I+1, J , K); + rCellNodes(2) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I+1, J+1, K); + rCellNodes(3) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I , J+1, K); + rCellNodes(4) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I , J , K+1); + rCellNodes(5) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I+1, J , K+1); + rCellNodes(6) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I+1, J+1, K+1); + rCellNodes(7) = GenerateOrRetrieveNode(rTheVolumeModelPart, rThisNodes, I , J+1, K+1); +} + + +void VoxelMesherEntityGeneration::GetQuadraticCellNodes( + Element::NodesArrayType& rCellNodes, + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K) +{ + /* 3----10----2 + * |\ |\ + * |15 23 | 14 + * 11 \ 20 9 \ + * | 7----18+---6 + * |24 | 26 | 22| + * 0---+-8----1 | + * \ 19 25 \ 17 + * 12 | 21 13| + * \| \| + * 4----16----5 + */ + GetLinearCellNodes(rCellNodes, rTheVolumeModelPart, rThisNodes, I, J, K); + + const std::size_t i = 2*I; + const std::size_t j = 2*J; + const std::size_t k = 2*K; + rCellNodes( 8) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j , k); + rCellNodes( 9) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+2, j+1, k); + rCellNodes(10) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+2, k); + rCellNodes(11) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i , j+1, k); + rCellNodes(12) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i , j , k+1); + rCellNodes(13) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+2, j , k+1); + rCellNodes(14) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+2, j+2, k+1); + rCellNodes(15) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i , j+2, k+1); + rCellNodes(16) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j , k+2); + rCellNodes(17) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+2, j+1, k+2); + rCellNodes(18) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+2, k+2); + rCellNodes(19) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i , j+1, k+2); + rCellNodes(20) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+1, k); + rCellNodes(21) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j , k+1); + rCellNodes(22) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+2, j+1, k+1); + rCellNodes(23) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+2, k+1); + rCellNodes(24) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i , j+1, k+1); + rCellNodes(25) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+1, k+2); + rCellNodes(26) = GenerateOrRetrieveQuadraticNode(rTheVolumeModelPart, rThisNodes, i+1, j+1, k+1); +} + + +void VoxelMesherEntityGeneration::InitializeQuadraticData() { + if (!mrModeler.mQuadraticNodeData.IsInitialized()) { + const auto& r_divisions = mrModeler.mMeshingData.GetNumberOfDivisions(); + mrModeler.mQuadraticNodeData.SetNumberOfDivisions(2*r_divisions[0], 2*r_divisions[1], 2*r_divisions[2]); + } +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/voxel_mesher_entity_generation.h b/kratos/modeler/entity_generation/voxel_mesher_entity_generation.h new file mode 100644 index 000000000000..1bd64f7657a8 --- /dev/null +++ b/kratos/modeler/entity_generation/voxel_mesher_entity_generation.h @@ -0,0 +1,117 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/kratos_parameters.h" +#include "modeler/voxel_mesh_generator_modeler.h" +#include "modeler/internals/cartesian_mesh_colors.h" +#include "modeler/internals/skin_intersection.h" + +namespace Kratos { + +class KRATOS_API(KRATOS_CORE) VoxelMesherEntityGeneration { + + VoxelMeshGeneratorModeler& mrModeler; + Parameters mParameters; + +public: + using CartesianMeshColors = Internals::CartesianMeshColors; + using SkinIntersection = Internals::SkinIntersection; + + KRATOS_CLASS_POINTER_DEFINITION(VoxelMesherEntityGeneration); + + VoxelMesherEntityGeneration(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters); + + virtual ~VoxelMesherEntityGeneration() = default; + + virtual void ValidateParameters(); + + virtual void Generate(); + + virtual void Generate(ModelPart& rModelPart, Parameters parameters) = 0; + +protected: + + Parameters GetParameters() const; + + virtual Parameters GetDefaultParameters() const; + + // internal interface to VoxelMeshGeneratorModeler + + ModelPart& GetModelPart(const std::string& rName) const; + + ModelPart& CreateAndGetModelPart(const std::string& rFullName) const; + + const CartesianMeshColors& GetMeshColors() const; + + Properties::Pointer CreateAndGetProperty(ModelPart& rModelPart, std::size_t PropertyId) const; + + const array_1d &GetNumberOfDivisions() const; + + const SkinIntersection& GetIntersections(int Color) const; + + SkinIntersection& GetIntersections(int Color); + + bool IntersectionsGenerated(int Color) const; + + void AddNodesToModelPart(ModelPart& rModelPart, ModelPart::NodesContainerType& rNewNodes) const; + + void SetStartIds(ModelPart& rModelPart); + + std::size_t GetStartElementId() const; + + std::size_t GetStartConditionId() const; + + array_1d GetNumberOfCells() const; + + Node::Pointer GenerateOrRetrieveNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K); + + Node::Pointer GenerateOrRetrieveQuadraticNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K); + + Node::Pointer GenerateNode(ModelPart& rModelPart, const Point& rCoordinates); + + void GetLinearCellNodes( + Element::NodesArrayType& rCellNodes, + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K); + + void GetQuadraticCellNodes( + Element::NodesArrayType& rCellNodes, + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K); + + void InitializeQuadraticData(); +}; + +} diff --git a/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.cpp b/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.cpp new file mode 100644 index 000000000000..55b09ce35743 --- /dev/null +++ b/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.cpp @@ -0,0 +1,40 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_entity_generation_factory.h" +#include "generate_elements_with_cell_color.h" +#include "generate_tetrahedral_elements_with_cell_color.h" +#include "generate_quadratic_elements_with_cell_color.h" +#include "generate_conditions_with_face_color.h" +#include "generate_triangular_conditions_with_face_color.h" +#include "generate_stl_intersection_with_cells.h" + +namespace Kratos { + +template class KratosComponents; + +void RegisterVoxelMesherEntityGeneration() +{ + VoxelMesherEntityGenerationFactory::Register("elements_with_cell_color"); + VoxelMesherEntityGenerationFactory::Register("tetrahedral_elements_with_cell_color"); + VoxelMesherEntityGenerationFactory::Register("quadratic_elements_with_cell_color"); + VoxelMesherEntityGenerationFactory::Register("conditions_with_face_color"); + VoxelMesherEntityGenerationFactory::Register("triangular_conditions_with_face_color"); + VoxelMesherEntityGenerationFactory::Register("stl_intersection_with_cells"); +} + +} \ No newline at end of file diff --git a/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.h b/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.h new file mode 100644 index 000000000000..e8d80c039aac --- /dev/null +++ b/kratos/modeler/entity_generation/voxel_mesher_entity_generation_factory.h @@ -0,0 +1,31 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "modeler/internals/voxel_mesher_component_factory.h" +#include "voxel_mesher_entity_generation.h" + +namespace Kratos { + +using VoxelMesherEntityGenerationFactory = VoxelMesherComponentFactory; + +KRATOS_API_EXTERN template class KRATOS_API(KRATOS_CORE) KratosComponents; + +void RegisterVoxelMesherEntityGeneration(); + +} \ No newline at end of file diff --git a/kratos/modeler/internals/cartesian_mesh_colors.h b/kratos/modeler/internals/cartesian_mesh_colors.h new file mode 100644 index 000000000000..081d420ce4cd --- /dev/null +++ b/kratos/modeler/internals/cartesian_mesh_colors.h @@ -0,0 +1,813 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + + +// System includes +#include +#include +#include + +// External includes + +// Project includes +#include "processes/process.h" +#include "includes/model_part.h" +#include "modeler/internals/cartesian_ray.h" +#include "utilities/parallel_utilities.h" + +namespace Kratos +{ + namespace Internals + { + class CartesianMeshColors{ + double mTolerance; + Point mMinPoint; + Point mMaxPoint; + array_1d, 3> mNodalCoordinates; + array_1d, 3> mElementCenterCoordinates; + std::vector> mNodalRayColors; + std::vector> mElementalRayColors; + std::vector mNodalColors; + std::vector mElementalColors; + std::vector> mElementalFaceColors; + DenseMatrix> mXYRays; + DenseMatrix> mXZRays; + DenseMatrix> mYZRays; + + inline std::size_t ElementIndex(std::size_t I, std::size_t J, std::size_t K) const { + return I + J * mElementCenterCoordinates[0].size() + K * mElementCenterCoordinates[1].size() * mElementCenterCoordinates[0].size(); + } + public: + CartesianMeshColors(): mTolerance(1e-12), mMinPoint(0.00, 0.00, 0.00), mMaxPoint(0.00, 0.00, 0.00){} + + std::vector const& GetNodalCoordinates(int Index) const {return mNodalCoordinates[Index];} + + std::vector const& GetElementCenterCoordinates(int Index) const {return mElementCenterCoordinates[Index];} + + template + void ExtendBoundingBox(TPointsContainerType const& Points, double Margine){ + for(auto const& point : Points){ + for(std::size_t i = 0; i<3; i++) + { + mMinPoint[i] = (mMinPoint[i] > point[i] - Margine) ? point[i] - Margine : mMinPoint[i]; + mMaxPoint[i] = (mMaxPoint[i] < point[i] + Margine) ? point[i] + Margine : mMaxPoint[i]; + } + } + } + + void SetCoordinates(std::vector const& rNodalXCoordinates, std::vector const& rNodalYCoordinates, std::vector const& rNodalZCoordinates){ + + KRATOS_ERROR_IF((rNodalXCoordinates.size() < 2) || (rNodalYCoordinates.size() < 2) || (rNodalZCoordinates.size() < 2)) + << "The coordinates should have at least two entries defining the bounding box." << std::endl; + + mNodalCoordinates[0] = rNodalXCoordinates; + mNodalCoordinates[1] = rNodalYCoordinates; + mNodalCoordinates[2] = rNodalZCoordinates; + + for(std::size_t i = 0 ; i < 3 ; i++){ + for(std::size_t j = 0 ; j < mNodalCoordinates[i].size() - 1 ; j++){ + double center_coordinate = (mNodalCoordinates[i][j] + mNodalCoordinates[i][j+1]) * .5; + mElementCenterCoordinates[i].push_back(center_coordinate); + } + } + + mXYRays.resize(mNodalCoordinates[0].size(),mNodalCoordinates[1].size(),false); + mXZRays.resize(mNodalCoordinates[0].size(),mNodalCoordinates[2].size(),false); + mYZRays.resize(mNodalCoordinates[1].size(),mNodalCoordinates[2].size(),false); + + mNodalRayColors.resize(mNodalCoordinates[0].size()*mNodalCoordinates[1].size()*mNodalCoordinates[2].size()); + mNodalColors.resize(mNodalCoordinates[0].size()*mNodalCoordinates[1].size()*mNodalCoordinates[2].size()); + mElementalRayColors.resize((mNodalCoordinates[0].size() - 1) * (mNodalCoordinates[1].size() - 1)*(mNodalCoordinates[2].size() - 1)); + mElementalColors.resize((mNodalCoordinates[0].size() - 1) * (mNodalCoordinates[1].size() - 1)*(mNodalCoordinates[2].size() - 1)); + mElementalFaceColors.resize((mNodalCoordinates[0].size() - 1) * (mNodalCoordinates[1].size() - 1)*(mNodalCoordinates[2].size() - 1)); + + Point min_point( mNodalCoordinates[0][0] - mTolerance, mNodalCoordinates[1][0] - mTolerance, mNodalCoordinates[2][0] - mTolerance); + Point max_point( mNodalCoordinates[0].back() + mTolerance, mNodalCoordinates[1].back() + mTolerance, mNodalCoordinates[2].back() + mTolerance); + + mMinPoint = min_point; + mMaxPoint = max_point; + + SetAllColors(0.00); + } + + void SetAllColors(double TheColor){ + + const std::size_t number_of_nodes = mNodalColors.size(); + for(std::size_t i = 0 ; i < number_of_nodes ; i++ ){ + mNodalRayColors[i] = ScalarVector(3,TheColor); + mNodalColors[i] = TheColor; + } + + const std::size_t number_of_elements = mElementalColors.size(); + for(std::size_t i = 0 ; i < number_of_elements ; i++ ){ + mElementalRayColors[i] = ScalarVector(3,TheColor); + mElementalColors[i] = TheColor; + mElementalFaceColors[i] = ScalarVector(6,TheColor); + } + } + + double& GetNodalColor(std::size_t I, std::size_t J, std::size_t K){ + const std::size_t index = I + J * mNodalCoordinates[0].size() + K * mNodalCoordinates[1].size() * mNodalCoordinates[0].size(); + return mNodalColors[index]; + } + + double& GetElementalColor(std::size_t I, std::size_t J, std::size_t K){ + return mElementalColors[ElementIndex(I, J, K)]; + } + + double GetElementalColor(std::size_t I, std::size_t J, std::size_t K) const { + return mElementalColors[ElementIndex(I, J, K)]; + } + + array_1d& GetElementalFaceColor(std::size_t I, std::size_t J, std::size_t K){ + return mElementalFaceColors[ElementIndex(I, J, K)]; + } + + const array_1d& GetElementalFaceColor(std::size_t I, std::size_t J, std::size_t K) const { + return mElementalFaceColors[ElementIndex(I, J, K)]; + } + + std::vector& GetNodalColors(){ return mNodalColors;} + + std::vector& GetElementalColors(){return mElementalColors;} + + std::vector>& GetElementalFaceColors(){return mElementalFaceColors;} + + Point GetPoint(std::size_t I, std::size_t J, std::size_t K) const { + return Point(mNodalCoordinates[0][I], mNodalCoordinates[1][J], mNodalCoordinates[2][K]); + } + + Point GetPoint(double I, double J, double K) const { + // The coordinates of the point are interpolated between those of floor(I, J, K) and ceil(I, J, K) + std::size_t i(I), j(J), k(K); + std::vector start{mNodalCoordinates[0][i], mNodalCoordinates[1][j], mNodalCoordinates[2][k]}; + return Point( + start[0] + (I-i)*(mNodalCoordinates[0][i+1]-start[0]), + start[1] + (J-j)*(mNodalCoordinates[1][j+1]-start[1]), + start[2] + (K-k)*(mNodalCoordinates[2][k+1]-start[2])); + } + + Point GetCenterOfElement(std::size_t I, std::size_t J, std::size_t K) const { + return Point(mElementCenterCoordinates[0][I], mElementCenterCoordinates[1][J], mElementCenterCoordinates[2][K]); + } + + CartesianRay& GetXYRay(std::size_t I, std::size_t J){ + return mXYRays(I,J); + } + + array_1d GetGridSize() const { + array_1d tmp{mNodalCoordinates[0].size(), mNodalCoordinates[1].size(), mNodalCoordinates[2].size()}; + return tmp; + } + + void InitializeRays(array_1d< std::size_t, 3 > const& MinRayPosition, array_1d< std::size_t, 3 > const& MaxRayPosition, const std::string& EntititesToColor){ + + std::vector* p_x_coordinates = &(mNodalCoordinates[0]); + std::vector* p_y_coordinates = &(mNodalCoordinates[1]); + std::vector* p_z_coordinates = &(mNodalCoordinates[2]); + + if((EntititesToColor == "center_of_elements") || (EntititesToColor == "face_of_elements")){ + p_x_coordinates = &(mElementCenterCoordinates[0]); + p_y_coordinates = &(mElementCenterCoordinates[1]); + p_z_coordinates = &(mElementCenterCoordinates[2]); + } + + + IndexPartition(MaxRayPosition[0]-MinRayPosition[0]).for_each([&](const std::size_t p) { + std::size_t i = MinRayPosition[0] + p; + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + mXYRays(i,j) = Internals::CartesianRay(2, + Point((*p_x_coordinates)[i], (*p_y_coordinates)[j], mMinPoint[2]), + Point((*p_x_coordinates)[i], (*p_y_coordinates)[j], mMaxPoint[2])); + } + }); + IndexPartition(MaxRayPosition[0]-MinRayPosition[0]).for_each([&](const std::size_t p) { + std::size_t i = MinRayPosition[0] + p; + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + mXZRays(i,k) = Internals::CartesianRay(1, + Point((*p_x_coordinates)[i], mMinPoint[1], (*p_z_coordinates)[k]), + Point((*p_x_coordinates)[i], mMaxPoint[1], (*p_z_coordinates)[k])); + } + }); + IndexPartition(MaxRayPosition[1]-MinRayPosition[1]).for_each([&](const std::size_t p) { + std::size_t j = MinRayPosition[1] + p; + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + mYZRays(j,k) = Internals::CartesianRay(0, + Point(mMinPoint[0], (*p_y_coordinates)[j], (*p_z_coordinates)[k]), + Point(mMaxPoint[0], (*p_y_coordinates)[j], (*p_z_coordinates)[k])); + } + }); + } + + void AddGeometry(Element::GeometryType const& rGeometry, bool IsNodal){ + array_1d< std::size_t, 3 > min_position; + array_1d< std::size_t, 3 > max_position; + if(IsNodal) { + CalculateMinMaxNodePositions(rGeometry, min_position, max_position); + } + else + { + CalculateMinMaxCenterOfElementPositions(rGeometry, min_position, max_position); + } + + // #pragma omp parallel for + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + mXYRays(i,j).AddIntersection(rGeometry, mTolerance); + } + } + + // #pragma omp parallel for + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + mXZRays(i,k).AddIntersection(rGeometry, mTolerance); + } + } + + // #pragma omp parallel for + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + mYZRays(j,k).AddIntersection(rGeometry, mTolerance); + } + } + + } + + void CalculateNodalRayColors(array_1d< std::size_t, 3 > const& MinRayPosition, array_1d< std::size_t, 3 > const& MaxRayPosition, int InsideColor, int OutsideColor){ + std::vector colors; + // #pragma omp parallel for + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + auto& ray = mXYRays(i,j); + ray.CollapseIntersectionPoints(mTolerance); + ray.CalculateColor(mNodalCoordinates[2], InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + if(colors[k] == InsideColor){ + GetNodalRayColor(i,j,k)[0] = colors[k]; + } + } + } + } + // #pragma omp parallel for + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + auto& ray = mXZRays(i,k); + ray.CollapseIntersectionPoints(mTolerance); + ray.CalculateColor(mNodalCoordinates[1], InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + if(colors[j] == InsideColor){ + GetNodalRayColor(i,j,k)[1] = colors[j]; + } + } + } + } + // #pragma omp parallel for + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + mYZRays(j,k).CollapseIntersectionPoints(mTolerance); + mYZRays(j,k).CalculateColor(mNodalCoordinates[0], InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + if(colors[i] == InsideColor){ + GetNodalRayColor(i,j,k)[2] = colors[i]; + } + } + } + } + + // #pragma omp parallel for + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + auto& ray_colors = GetNodalRayColor(i,j,k); + std::size_t n_inside = 0; + std::size_t n_outside = 0; + for(std::size_t dim = 0 ; dim < 3 ; dim++){ + if(ray_colors[dim] == InsideColor){ + n_inside++; + } + else { + n_outside++; + } + } + GetNodalColor(i,j,k) = (n_inside > n_outside) ? InsideColor : OutsideColor; + } + } + } + } + + void CalculateElementalRayColors(array_1d< std::size_t, 3 > const& MinRayPosition, array_1d< std::size_t, 3 > const& MaxRayPosition, int InsideColor, int OutsideColor){ + std::vector colors; + std::vector x_coordinates(mNodalCoordinates[0].size() - 1); + std::vector y_coordinates(mNodalCoordinates[1].size() - 1); + std::vector z_coordinates(mNodalCoordinates[2].size() - 1); + + for(std::size_t i = 0 ; i < x_coordinates.size() ; i++){ + x_coordinates[i] = (mNodalCoordinates[0][i] + mNodalCoordinates[0][i+1]) * 0.5; + } + + for(std::size_t i = 0 ; i < y_coordinates.size() ; i++){ + y_coordinates[i] = (mNodalCoordinates[1][i] + mNodalCoordinates[1][i+1]) * 0.5; + } + + for(std::size_t i = 0 ; i < z_coordinates.size() ; i++){ + z_coordinates[i] = (mNodalCoordinates[2][i] + mNodalCoordinates[2][i+1]) * 0.5; + } + + // #pragma omp parallel for + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + auto& ray = mXYRays(i,j); + ray.CollapseIntersectionPoints(mTolerance); + ray.CalculateColor(z_coordinates, InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + if(colors[k] == InsideColor){ + GetElementalRayColor(i,j,k)[0] = colors[k]; + } + } + } + } + // #pragma omp parallel for + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + auto& ray = mXZRays(i,k); + ray.CollapseIntersectionPoints(mTolerance); + ray.CalculateColor(y_coordinates, InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + if(colors[j] == InsideColor){ + GetElementalRayColor(i,j,k)[1] = colors[j]; + } + } + } + } + // #pragma omp parallel for + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + mYZRays(j,k).CollapseIntersectionPoints(mTolerance); + mYZRays(j,k).CalculateColor(x_coordinates, InsideColor, OutsideColor, colors, mTolerance); + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + if(colors[i] == InsideColor){ + GetElementalRayColor(i,j,k)[2] = colors[i]; + } + } + } + } + // #pragma omp parallel for + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + for(std::size_t i = MinRayPosition[0] ; i < MaxRayPosition[0] ; i++){ + auto& ray_colors = GetElementalRayColor(i,j,k); + std::size_t n_inside = 0; + std::size_t n_outside = 0; + for(std::size_t dim = 0 ; dim < 3 ; dim++){ + if(ray_colors[dim] == InsideColor){ + n_inside++; + } + else { + n_outside++; + } + } + auto& color = GetElementalColor(i,j,k); + color = (n_inside > n_outside) ? InsideColor : color; + } + } + } + + } + + void CalculateElementalFaceColors(array_1d< std::size_t, 3 > const& MinRayPosition, array_1d< std::size_t, 3 > const& MaxRayPosition, int FaceColor, int OutsideColor, int VolumeColor){ + if(FaceColor == OutsideColor) + return; // Nothing to do! + + + const std::size_t size_x = mElementCenterCoordinates[0].size(); + const std::size_t size_y = mElementCenterCoordinates[1].size(); + const std::size_t size_z = mElementCenterCoordinates[2].size(); + + std::vector x_coordinates(size_x + 2); + std::vector y_coordinates(size_y + 2); + std::vector z_coordinates(size_z + 2); + + x_coordinates.front() = mMinPoint[0]; + y_coordinates.front() = mMinPoint[1]; + z_coordinates.front() = mMinPoint[2]; + + for(std::size_t i = 0 ; i < size_x ; i++){ + x_coordinates[i+1] = mElementCenterCoordinates[0][i]; + } + + for(std::size_t i = 0 ; i < size_y ; i++){ + y_coordinates[i+1] = mElementCenterCoordinates[1][i]; + } + + for(std::size_t i = 0 ; i < size_z ; i++){ + z_coordinates[i+1] = mElementCenterCoordinates[2][i]; + } + + x_coordinates.back() = mMaxPoint[0]; + y_coordinates.back() = mMaxPoint[1]; + z_coordinates.back() = mMaxPoint[2]; + + IndexPartition(MaxRayPosition[0]-MinRayPosition[0]).for_each( + std::vector(), [&](const std::size_t p, std::vector& rColors) { + std::size_t i = MinRayPosition[0] + p; + for(std::size_t j = MinRayPosition[1] ; j < MaxRayPosition[1] ; j++){ + auto& ray = mXYRays(i,j); + ray.CollapseIntersectionPoints(mTolerance); + ray.MarkIntersectedIntervals(z_coordinates, FaceColor, OutsideColor, rColors, mTolerance); + + double previous_center_color = OutsideColor; + for(std::size_t k = 0 ; k < size_z; k++){ + auto next_center_color = GetElementalColor(i,j,k); + auto interval_color = rColors[k]; + if(interval_color == FaceColor){ + if((previous_center_color == VolumeColor) && (next_center_color != VolumeColor)){ + GetElementalFaceColor(i,j,k-1)[5] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((previous_center_color != VolumeColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i,j,k)[2] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((k > 1) && (rColors[k-2] == VolumeColor)){ + GetElementalFaceColor(i,j,k-2)[5] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((k < size_z - 1) && (rColors[k+1] == VolumeColor)){ + GetElementalFaceColor(i,j,k+1)[2] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(i,j,k)[2] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING("CartesianMesh") << "The given interface is not in the interface of the volume for cell [" << i << "," << j << "," << k << "]" << std::endl; + } + } + previous_center_color = next_center_color; + } + if(rColors.back() == FaceColor){ + if(previous_center_color == VolumeColor){ + GetElementalFaceColor(i,j,size_z-1)[5] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(i,j,size_z-1)[5] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING("CartesianMesh") << "The given interface is not in the interface of the volume for cell [" << i << "," << j << "," << size_z-1 << "]" << std::endl; + } + } + } + } + ); + + IndexPartition(MaxRayPosition[0]-MinRayPosition[0]).for_each( + std::vector(), [&](const std::size_t p, std::vector& rColors) { + std::size_t i = MinRayPosition[0] + p; + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + auto& ray = mXZRays(i,k); + ray.CollapseIntersectionPoints(mTolerance); + ray.MarkIntersectedIntervals(y_coordinates, FaceColor, OutsideColor, rColors, mTolerance); + double previous_center_color = OutsideColor; + for(std::size_t j = 0 ; j < size_y ; j++){ + auto next_center_color = GetElementalColor(i,j,k); + auto interval_color = rColors[j]; + if(interval_color == FaceColor){ + if((previous_center_color == VolumeColor) && (next_center_color != VolumeColor)){ + GetElementalFaceColor(i,j-1,k)[4] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((previous_center_color != VolumeColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i,j,k)[1] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((j > 1) && (rColors[j-2] == VolumeColor)){ + GetElementalFaceColor(i,j-2,k)[4] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((j < size_y - 1) && (rColors[j+1] == VolumeColor)){ + GetElementalFaceColor(i,j+1,k)[1] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(i,j,k)[1] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING("CartesianMesh") << "The given interface is not in the interface of the volume for cell [" << i << "," << j << "," << k << "]" << std::endl; + } + } + previous_center_color = next_center_color; + } + if(rColors.back() == FaceColor){ + if(previous_center_color == VolumeColor){ + GetElementalFaceColor(i, size_y-1,k)[4] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(i, size_y-1,k)[4] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING("CartesianMesh") << "The given interface is not in the interface of the volume for cell [" << i << "," << size_y-1 << "," << k << "]" << std::endl; + } + } + } + } + ); + + IndexPartition(MaxRayPosition[1]-MinRayPosition[1]).for_each( + std::vector(), [&](const std::size_t p, std::vector& rColors) { + std::size_t j = MinRayPosition[1] + p; + for(std::size_t k = MinRayPosition[2] ; k < MaxRayPosition[2] ; k++){ + auto& ray= mYZRays(j,k); + ray.CollapseIntersectionPoints(mTolerance); + ray.MarkIntersectedIntervals(x_coordinates, FaceColor, OutsideColor, rColors, mTolerance); + double previous_center_color = OutsideColor; + for(std::size_t i = 0 ; i < size_x ; i++){ + auto next_center_color = GetElementalColor(i,j,k); + auto interval_color = rColors[i]; + if(interval_color == FaceColor){ + if((previous_center_color == VolumeColor) && (next_center_color != VolumeColor)){ + GetElementalFaceColor(i-1,j,k)[3] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((previous_center_color != VolumeColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i,j,k)[0] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((i > 1) && (rColors[i-2] == VolumeColor)){ + GetElementalFaceColor(i-2,j,k)[3] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((i < size_x - 1) && (rColors[i+1] == VolumeColor)){ + GetElementalFaceColor(i+1,j,k)[0] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(i,j,k)[0] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING("VoxelMesher") << "The given interface is not in the interface of the volume for cell [" << i << "," << j << "," << k << "]" << std::endl; + } + } + previous_center_color = next_center_color; + } + if(rColors.back() == FaceColor){ + if(previous_center_color == VolumeColor){ + GetElementalFaceColor(size_x-1,j,k)[3] = FaceColor; // [-x,-y,-z,x,y,z] + } + else{ + GetElementalFaceColor(size_x-1,j,k)[3] = -FaceColor; // Error color is the -FaceColor + // KRATOS_WARNING << "The given interface is not in the interface of the volume for cell [" << size_x-1 << "," << j << "," << k << "]" << std::endl; + } + } + } + } + ); + } + + void CalculateElementalFaceColorsBetweenColors(int FaceColor, int OutsideColor, int VolumeColor){ + if(FaceColor == OutsideColor) + return; // Nothing to do! + + const std::size_t size_x = mElementCenterCoordinates[0].size(); + const std::size_t size_y = mElementCenterCoordinates[1].size(); + const std::size_t size_z = mElementCenterCoordinates[2].size(); + + // First we look in the Z direction + IndexPartition(size_x).for_each([&](const std::size_t i) { + for(std::size_t j = 0 ; j < size_y ; j++){ + for(std::size_t k = 1 ; k < size_z; k++){ + auto next_center_color = GetElementalColor(i,j,k); + auto current_color = GetElementalColor(i,j,k-1); + if((current_color == VolumeColor) && (next_center_color == OutsideColor)){ + GetElementalFaceColor(i,j,k-1)[5] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((current_color == OutsideColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i,j,k)[2] = FaceColor; // [-x,-y,-z,x,y,z] + } + } + } + }); + + // Now we look in the Y Direction + IndexPartition(size_x).for_each([&](const std::size_t i) { + for(std::size_t j = 1 ; j < size_y ; j++){ + for(std::size_t k = 0 ; k < size_z; k++){ + auto next_center_color = GetElementalColor(i,j,k); + auto current_color = GetElementalColor(i,j-1,k); + if((current_color == VolumeColor) && (next_center_color == OutsideColor)){ + GetElementalFaceColor(i,j-1,k)[4] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((current_color == OutsideColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i,j,k)[1] = FaceColor; // [-x,-y,-z,x,y,z] + } + + } + } + }); + // Now we look in the X Direction + IndexPartition(size_x-1).for_each([&](const std::size_t i) { + for(std::size_t j = 0 ; j < size_y ; j++){ + for(std::size_t k = 0 ; k < size_z; k++){ + auto next_center_color = GetElementalColor(i+1,j,k); + auto current_color = GetElementalColor(i,j,k); + if((current_color == VolumeColor) && (next_center_color == OutsideColor)){ + GetElementalFaceColor(i,j,k)[3] = FaceColor; // [-x,-y,-z,x,y,z] + } + else if((current_color == OutsideColor) && (next_center_color == VolumeColor)){ + GetElementalFaceColor(i+1,j,k)[0] = FaceColor; // [-x,-y,-z,x,y,z] + } + } + } + }); + + } + + template + void CalculateOuterMinMaxNodePositions(TPointsContainerType const& Points, array_1d< std::size_t, 3 >& MinNodePosition, array_1d< std::size_t, 3 >& MaxNodePosition) const{ + if(Points.empty()) + return; + + Point min_point; + Point max_point; + + CalculateMinMaxPoints(Points, min_point, max_point); + + for(std::size_t i = 0; i < 3; i++ ) { + auto min_position = CalculateNodePosition( min_point[i] - mTolerance, i ); + MinNodePosition[ i ] = (min_position == 0) ? 0 : min_position - 1; + MaxNodePosition[ i ] = CalculateNodePosition( max_point[i] + mTolerance, i ); + } + } + + template + void CalculateMinMaxNodePositions(TPointsContainerType const& Points, array_1d< std::size_t, 3 >& MinNodePosition, array_1d< std::size_t, 3 >& MaxNodePosition){ + if(Points.empty()) + return; + + Point min_point; + Point max_point; + + CalculateMinMaxPoints(Points, min_point, max_point); + + for(std::size_t i = 0; i < 3; i++ ) { + MinNodePosition[ i ] = CalculateNodePosition( min_point[i], i ); + MaxNodePosition[ i ] = CalculateNodePosition( max_point[i], i ) + 1; + } + } + + template + void CalculateMinMaxPoints(TPointsContainerType const& Points, Point& MinPoint, Point& MaxPoint) const { + if(Points.empty()) + return; + + MinPoint = *(Points.begin()); + MaxPoint = *(Points.begin()); + for(auto const& point : Points){ + for(std::size_t i = 0; i<3; i++) + { + MinPoint[i] = (MinPoint[i] > point[i] ) ? point[i] : MinPoint[i]; + MaxPoint[i] = (MaxPoint[i] < point[i] ) ? point[i] : MaxPoint[i]; + } + } + } + + template + void CalculateMinMaxCenterOfElementPositions(TPointsContainerType const& Points, array_1d< std::size_t, 3 >& MinNodePosition, array_1d< std::size_t, 3 >& MaxNodePosition){ + if(Points.empty()) + return; + + Point min_point = *(Points.begin()); + Point max_point = *(Points.begin()); + for(auto const& point : Points){ + for(std::size_t i = 0; i<3; i++) + { + min_point[i] = (min_point[i] > point[i] ) ? point[i] : min_point[i]; + max_point[i] = (max_point[i] < point[i] ) ? point[i] : max_point[i]; + } + } + + for(std::size_t i = 0; i < 3; i++ ) { + MinNodePosition[ i ] = CalculateCenterOfElementPosition( min_point[i], i ); + MaxNodePosition[ i ] = CalculateCenterOfElementPosition( max_point[i], i ) + 1; + } + } + + std::size_t CalculateNodePosition( double Coordinate, int ThisDimension ) const { + auto const& coordinates = mNodalCoordinates[ThisDimension]; + auto i_min = std::lower_bound(coordinates.begin(), coordinates.end(), Coordinate); + if(i_min == coordinates.end()) + return coordinates.size() - 1; + + return std::distance(coordinates.begin(), i_min); + } + + std::size_t CalculateCenterOfElementPosition( double Coordinate, int ThisDimension ) const { + auto const& coordinates = mElementCenterCoordinates[ThisDimension]; + auto i_min = std::lower_bound(coordinates.begin(), coordinates.end(), Coordinate); + if(i_min == coordinates.end()) + return coordinates.size() - 1; + + return std::distance(coordinates.begin(), i_min); + } + + + + void WriteParaViewVTR(std::string const& Filename) { + std::ofstream output_file(Filename); + + output_file << "" << std::endl; + output_file << "" << std::endl; + output_file << "" << std::endl; + output_file << " " << std::endl; + output_file << "" << std::endl; + for (auto i_x : mNodalCoordinates[0]) { + output_file << i_x << " "; + } + output_file << " " << std::endl; + output_file << "" + << std::endl; + for (auto i_y : mNodalCoordinates[1]) { + output_file << i_y << " "; + } + output_file << " " << std::endl; + output_file << "" << std::endl; + for (auto i_z : mNodalCoordinates[2]) { + output_file << i_z << " "; + } + output_file << " " << std::endl; + output_file << " " << std::endl; + + output_file << "" << std::endl; + for(std::size_t i = 0 ; i < 3 ; i++){ + output_file << "" << std::endl; + + for (auto& color: mNodalRayColors) { + output_file << color[i] << " "; + } + output_file << std::endl; + output_file << " " << std::endl; + } + output_file << " " << std::endl; + output_file << "" << std::endl; + for(std::size_t i = 0 ; i < 3 ; i++){ + output_file << "" << std::endl; + + for (auto& color: mElementalRayColors) { + output_file << color[i] << " "; + } + output_file << std::endl; + output_file << " " << std::endl; + } + for(std::size_t i = 0 ; i < 6 ; i++){ + output_file << "" << std::endl; + + for (auto& color: mElementalFaceColors) { + output_file << color[i] << " "; + } + output_file << std::endl; + output_file << " " << std::endl; + } + output_file << "" << std::endl; + + for (auto& color: mElementalColors) { + output_file << color << " "; + } + output_file << std::endl; + output_file << " " << std::endl; + output_file << " " << std::endl; + + output_file << "" << std::endl; + output_file << "" << std::endl; + output_file << "" << std::endl; + } + + void PrintAllVoxelColorsToAsciiFile(const std::string& filename) { + std::ofstream file_out(filename); + + const std::size_t ncols = mElementCenterCoordinates[0].size(); + file_out << "NCOLS " << ncols <<"\n"; + const std::size_t nrows = mElementCenterCoordinates[1].size(); + file_out << "NROWS " << nrows <<"\n"; + const std::size_t nlayers = mElementCenterCoordinates[2].size(); + file_out << "NLAYERS " << nlayers <<"\n"; + file_out << "XLLCORNER " << mNodalCoordinates[0][0] <<"\n"; + file_out << "YLLCORNER " << mNodalCoordinates[1][0] <<"\n"; + file_out << "ZLLCORNER " << mNodalCoordinates[2][0] <<"\n"; + + file_out << "XCELLSIZE " << (mNodalCoordinates[0].back() - mNodalCoordinates[0][0]) / ncols <<"\n"; + file_out << "YCELLSIZE " << (mNodalCoordinates[1].back() - mNodalCoordinates[1][0]) / nrows <<"\n"; + file_out << "ZCELLSIZE " << (mNodalCoordinates[2].back() - mNodalCoordinates[2][0]) / nlayers <<"\n"; + file_out << "NODATA_VALUE -9999 \n"; + for(std::size_t k=0; k0; --j) { // ESRI grids consider Y axis downwards (https://en.wikipedia.org/wiki/Esri_grid) + for(std::size_t i=0; i& GetNodalRayColor(std::size_t I, std::size_t J, std::size_t K){ + const std::size_t index = I + J * mNodalCoordinates[0].size() + K * mNodalCoordinates[1].size() * mNodalCoordinates[0].size(); + return mNodalRayColors[index]; + } + + array_1d& GetElementalRayColor(std::size_t I, std::size_t J, std::size_t K){ + const std::size_t index = I + J * (mNodalCoordinates[0].size() - 1) + K * (mNodalCoordinates[1].size() - 1) * (mNodalCoordinates[0].size() - 1); + return mElementalRayColors[index]; + } + + }; + } +} // namespace Kratos. diff --git a/kratos/modeler/internals/cartesian_ray.h b/kratos/modeler/internals/cartesian_ray.h new file mode 100644 index 000000000000..471d7e8a335d --- /dev/null +++ b/kratos/modeler/internals/cartesian_ray.h @@ -0,0 +1,404 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes +#include +#include + +// External includes + +// Project includes +#include "includes/define.h" +#include "utilities/intersection_utilities.h" + + +namespace Kratos +{ +namespace Internals +{ + +///@addtogroup KratosCore +///@{ + +///@name Kratos Classes +///@{ + +/// A cartesian ray to be used in ray casting operations +/** This class represents a cartesian ray in 3D space defined by a direction and Point1 and Point2 +*/ +template +class CartesianRay +{ +public: + ///@name Type Definitions + ///@{ + + /// Pointer definition of CartesianRay + KRATOS_CLASS_POINTER_DEFINITION(CartesianRay); + + ///@} + ///@name Life Cycle + ///@{ + + /// Default constructor. + CartesianRay(): mIsValid(true), mDirection(0), mPoint1(), mPoint2() {} + + /// Constructor with all needed parameters + CartesianRay(int Direction, Point const& Point1, Point const& Point2): mIsValid(true), mDirection(Direction), mPoint1(Point1), mPoint2(Point2) {} + + // Copy constructor + CartesianRay(CartesianRay const& Other): mIsValid(Other.mIsValid), mDirection(Other.mDirection), mPoint1(Other.mPoint1), mPoint2(Other.mPoint2), mIntersections(Other.mIntersections) {} + + /// Destructor. + virtual ~CartesianRay(){} + + ///@} + ///@name Operators + ///@{ + + CartesianRay& operator=(CartesianRay const& Other){ + mIsValid = Other.mIsValid; + mDirection = Other.mDirection; + mPoint1 = Other.mPoint1; + mPoint2 = Other.mPoint2; + mIntersections = Other.mIntersections; + + return *this; + } + + + ///@} + ///@name Operations + ///@{ + + void AddIntersection(TGeometryType const& rGeometry, double Tolerance){ + + array_1d intersection_point = ZeroVector(3); + const double relative_tolerance = 1.0e-12*std::sqrt(rGeometry.Length()); + const int is_intersected = ComputeTriangleRayIntersection( + rGeometry, + mPoint1, + mPoint2, + intersection_point, + relative_tolerance); + + if(is_intersected == 1){ // There is an intersection but not coplanar + mIntersections.push_back(std::make_pair(intersection_point[mDirection], &rGeometry)); + } + } + + void CollapseIntersectionPoints(double Tolerance){ + + if (mIntersections.size() < 2) { + return; + } + // Sort + std::sort(mIntersections.begin(), mIntersections.end()); + auto i_unique_end = mIntersections.begin(); + auto i_patch_begin = mIntersections.begin(); + auto i_patch_end = mIntersections.begin(); + for(auto i_intersection = mIntersections.begin() + 1 ; i_intersection != mIntersections.end() ; i_intersection++) { + if (std::abs(i_intersection->first - i_patch_begin->first) < Tolerance){ // we are in a patch so let's continue until the patch finishes + i_patch_end = i_intersection; + if(i_intersection + 1 != mIntersections.end()) { // if i_intersection is not the last one we keep continuing + continue; + } + } + if((i_patch_begin == i_patch_end) || // The previous patch was only one intersection and we add it. + (CheckPassingThroughByExtraRays(i_patch_begin, i_patch_end+1, Tolerance, 2.00*Tolerance))) { // more than one intersection to be checked with extra rays + if(i_unique_end != i_patch_begin) { + *i_unique_end = std::move(*i_patch_begin); + } + i_unique_end++; + } + if((i_intersection != i_patch_end)&&(i_intersection + 1 == mIntersections.end())) { // Adding the last intersection + if(i_unique_end != i_intersection) { + *i_unique_end = std::move(*i_intersection); + } + i_unique_end++; + } + i_patch_begin = i_intersection; + i_patch_end = i_intersection; + } + auto new_size = std::distance(mIntersections.begin(), i_unique_end); + mIntersections.resize(new_size); + } + + void CalculateColor(std::vector const& Coordinates, int InsideColor, int OutsideColor, std::vector& ResultingColors, double NearEnough){ + + bool is_inside=false; + + if(ResultingColors.size() != Coordinates.size()){ + ResultingColors.resize(Coordinates.size()); + } + + std::size_t current_index=0; + const std::size_t size = Coordinates.size(); + + for(auto& i_intersection : mIntersections){ + while(current_index < size){ + if((i_intersection.first - Coordinates[current_index]) > NearEnough){ + ResultingColors[current_index++] = (is_inside) ? InsideColor : OutsideColor; + } else if((i_intersection.first - Coordinates[current_index]) > -NearEnough){ // Considering very near to wall as inside + ResultingColors[current_index++] = InsideColor; + } + else{ + break; + } + } + is_inside = !is_inside; + } + + mIsValid = !is_inside; // Ray is not valid if is_inside is true after the last intersection + + // now coloring the points after the last intersection as outside + while(current_index < size){ + ResultingColors[current_index++] = OutsideColor; + } + } + + void MarkIntersectedIntervals(std::vector const& Coordinates, int InsideColor, int OutsideColor, std::vector& ResultingColors, double NearEnough){ + + const std::size_t size = Coordinates.size() - 1; + + if(ResultingColors.size() != Coordinates.size()){ + ResultingColors.resize(size); + } + + std::size_t current_index=0; + + for(auto& i_intersection : mIntersections){ + while(current_index < size){ + if((i_intersection.first - Coordinates[current_index+1]) > NearEnough){ + ResultingColors[current_index++] = OutsideColor; + } + else{ + ResultingColors[current_index++] = InsideColor; + break; + } + } + } + + // now coloring the points after the last intersection as outside + while(current_index < size){ + ResultingColors[current_index++] = OutsideColor; + } + } + + + ///@} + ///@name Access + ///@{ + + std::vector> const& GetIntersections() const {return mIntersections;} + + Point& GetPoint1(){return mPoint1;} + + Point& GetPoint2(){return mPoint2;} + + + ///@} + ///@name Inquiry + ///@{ + + bool IsValid(){return mIsValid;} + + ///@} + ///@name Input and output + ///@{ + + /// Turn back information as a string. + virtual std::string Info() const + { + std::stringstream buffer; + buffer << "CartesianRay" ; + return buffer.str(); + } + + /// Print information about this object. + virtual void PrintInfo(std::ostream& rOStream) const {rOStream << "CartesianRay";} + + /// Print object's data. + virtual void PrintData(std::ostream& rOStream) const {} + + ///@} + ///@name Friends + ///@{ + + + ///@} +private: + ///@name Static Member Variables + ///@{ + + + ///@} + ///@name Member Variables + ///@{ + + bool mIsValid; + int mDirection; + Point mPoint1; + Point mPoint2; + std::vector> mIntersections; + + ///@} + ///@name Private Operators + ///@{ + + + ///@} + ///@name Private Operations + ///@{ + + + bool CheckPassingThroughByExtraRays(typename std::vector>::iterator Begin, typename std::vector>::iterator End, double Tolerance, double Delta){ + const std::array delta_u{Delta, Delta, 0.00, -Delta, -Delta, -Delta, 0.00, Delta}; + const std::array delta_v{0.00, Delta, Delta, Delta, 0.00, -Delta, -Delta, -Delta}; + const std::array axes{1,2,0,1}; + + const std::size_t i_u = axes[mDirection]; + const std::size_t i_v = axes[mDirection+1]; + + std::size_t no_hit_cases = 0; + + for(std::size_t i_ray = 0 ; i_ray < 8 ; i_ray++){ + CartesianRay extra_ray(mDirection, mPoint1, mPoint2); + extra_ray.mPoint1[i_u] += delta_u[i_ray]; + extra_ray.mPoint1[i_v] += delta_v[i_ray]; + extra_ray.mPoint2[i_u] += delta_u[i_ray]; + extra_ray.mPoint2[i_v] += delta_v[i_ray]; + + for(auto i_intersection = Begin ; i_intersection != End; i_intersection++){ + extra_ray.AddIntersection(*(i_intersection->second), Tolerance); + } + if(extra_ray.mIntersections.size() == 0){ + no_hit_cases++; + } + if(no_hit_cases > 4) // more than half + return false; + } + return true; + } + + /** + * Find the 3D intersection of a ray with a triangle ignoring the coplanar and degenerated situations + * Todo: To be passed to the intersection_utilities.h in core + * @param rTriangleGeometry Is the triangle to intersect + * @param rLinePoint1 Coordinates of the first point of the intersecting line + * @param rLinePoint2 Coordinates of the second point of the intersecting line + * @return rIntersectionPoint The intersection point coordinates + * @return The intersection type index: + * -1 (the triangle is degenerate) + * 0 (disjoint - no intersection) + * 1 (intersect in a unique point) + * 2 (are in the same plane) + */ + + static int ComputeTriangleRayIntersection( + const TGeometryType& rTriangleGeometry, + const array_1d& rLinePoint1, + const array_1d& rLinePoint2, + array_1d& rIntersectionPoint, + const double epsilon = 1e-12) { + + // This is the adaption of the implemnetation of Moller-Trumbore algorithm provided in: + // https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm + + const array_1d edge1 = rTriangleGeometry[1] - rTriangleGeometry[0]; + const array_1d edge2 = rTriangleGeometry[2] - rTriangleGeometry[0]; + const array_1d line_vector = rLinePoint2 - rLinePoint1; + array_1d h; + MathUtils::CrossProduct(h, line_vector, edge2); + double a = inner_prod(edge1,h); + if (a > -epsilon && a < epsilon) + return 0; // This ray is parallel to this triangle. + const double f = 1.0/a; + const array_1d s = rLinePoint1 - rTriangleGeometry[0]; + const double u = f * inner_prod(s,h); + if (u < -epsilon || u > 1.0 + epsilon) + return 0; + array_1d q; + MathUtils::CrossProduct(q, s, edge1); + const double v = f * inner_prod(line_vector,q); + if (v < -epsilon || u + v > 1.0 + epsilon) + return 0; + // At this stage we can compute t to find out where the intersection point is on the line. + float t = f * inner_prod(edge2,q); + if (t > epsilon && t < 1.00/epsilon) // ray intersection + { + rIntersectionPoint = rLinePoint1 + line_vector * t; + return 1; + } + else // This means that there is a line intersection but not a ray intersection. + return 0; + } + + + + ///@} + ///@name Private Access + ///@{ + + + ///@} + ///@name Private Inquiry + ///@{ + + + ///@} + ///@name Un accessible methods + ///@{ + + ///@} + +}; // Class CartesianRay + +///@} + +///@name Type Definitions +///@{ + + +///@} +///@name Input and output +///@{ + + +/// input stream function +template +inline std::istream& operator >> (std::istream& rIStream, + CartesianRay& rThis){ + return rIStream; + } + +/// output stream function +template +inline std::ostream& operator << (std::ostream& rOStream, + const CartesianRay& rThis) +{ + rThis.PrintInfo(rOStream); + rOStream << std::endl; + rThis.PrintData(rOStream); + + return rOStream; +} +///@} + +///@} addtogroup block + +} // namespace Internals + +} // namespace Kratos. + diff --git a/kratos/modeler/internals/skin_intersection.h b/kratos/modeler/internals/skin_intersection.h new file mode 100644 index 000000000000..ae7e0143feb6 --- /dev/null +++ b/kratos/modeler/internals/skin_intersection.h @@ -0,0 +1,289 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Jordi Cotela +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/ublas_interface.h" +#include "utilities/divide_triangle_3d_3.h" + +namespace Kratos::Internals { + +class SkinIntersection +{ +public: + using SplitGeometryType = DivideTriangle3D3>::IndexedPointGeometryType; + using SplitGeometryPointerType = SplitGeometryType::Pointer; + using SplitGeometryPointType = DivideTriangle3D3>::IndexedPointType; + using SplitGeometryPointsArrayType = Kratos::PointerVector; + + SkinIntersection(const array_1d& NumDivisions): + mNumDivisions(NumDivisions), + mCutGeometries(NumDivisions[0]*NumDivisions[1]*NumDivisions[2]) + {} + + ~SkinIntersection() = default; + + + template + static const SplitGeometryPointerType ConvertToWorkGeometry(const GeometryType& rGeometry) { + SplitGeometryPointsArrayType points; + points.reserve(rGeometry.size()); + std::size_t index = 0; + for (const auto& point: rGeometry) { + points.push_back(Kratos::make_shared(point.Coordinates(), ++index)); + } + return Kratos::make_shared>(points); + } + + + void ComputeCutInsideCell( + SplitGeometryPointerType pGeometry, + const Point& rLowPoint, + const Point& rHighPoint, + std::size_t I, + std::size_t J, + std::size_t K) + { + std::vector geometries; + geometries.push_back(pGeometry); + + for (std::size_t i = 0; i < 3; i++) { + geometries = TrimLower(geometries, rLowPoint, i); + geometries = TrimHigher(geometries, rHighPoint, i); + } + + auto& r_cell_geometries = CutGeometriesInCell(I, J, K); + r_cell_geometries.insert(r_cell_geometries.end(), geometries.begin(), geometries.end()); + } + + const std::vector& CutGeometriesInCell(std::size_t I, std::size_t J, std::size_t K) const + { + return mCutGeometries[K + mNumDivisions[2]*(J + mNumDivisions[1]*I)]; + } + + + double GetIntegrationPointData( + std::vector& rIntegrationPointData, + const Point& rLowPoint, + const Point& rHighPoint, + std::size_t I, + std::size_t J, + std::size_t K, + const GeometryData::IntegrationMethod Method, + double Thickness) const + { + rIntegrationPointData.resize(0); + auto& r_cut_geometries = CutGeometriesInCell(I, J, K); + + for (auto& p_geom: r_cut_geometries) { + AddTriangleIntegrationPointData(rIntegrationPointData, *p_geom, Method); + } + + // Assuming that the element is a hexahedra with plane faces and local coordinates in [-1,1]^3 + array_1d len = rHighPoint - rLowPoint; + double vol = len[0]*len[1]*len[2]; + double weight_factor = Thickness*8.0/vol; // Integration point weights add to 8 for hexas + double effective_area = 0.0; + + for (auto& r_data: rIntegrationPointData) { + for (std::size_t d = 0; d < 3; d++) { + r_data[d] = 2*(r_data[d] - rLowPoint[d])/len[d] - 1; + } + effective_area += r_data[3]; + r_data[3] *= weight_factor; + //TODO: PointIsOnSharedFace should account for same-color neighbors only + //if (PointIsOnSharedFace(r_data, I, J, K)) { + // r_data[3] *= 0.5*weight_factor; + //} + //else { + // r_data[3] *= weight_factor; + //} + } + + const double full_fraction = Thickness*effective_area / vol; + return full_fraction; + } + +private: + array_1d mNumDivisions; + std::vector> mCutGeometries = {}; + + std::vector& CutGeometriesInCell(std::size_t I, std::size_t J, std::size_t K) + { + return mCutGeometries[K + mNumDivisions[2]*(J + mNumDivisions[1]*I)]; + } + + template + static std::size_t SignedDistanceUnder( + Vector& rNodalDistances, + const GeometryType& rGeometry, + const Point& rReferencePoint, + const std::size_t Component) + { + auto num_nodes = rGeometry.PointsNumber(); + if (rNodalDistances.size() != num_nodes) { + rNodalDistances.resize(num_nodes); + noalias(rNodalDistances) = ZeroVector(num_nodes); + } + + auto idistance = rNodalDistances.begin(); + const double reference_coord = rReferencePoint[Component]; + std::size_t points_under = 0; + + for (const auto& point: rGeometry) { + const double d = reference_coord - point[Component]; + if (d >= 0) points_under++; + *(idistance++) = d; + } + + return points_under; + } + + + + template + static std::size_t SignedDistanceOver( + Vector& rNodalDistances, + const GeometryType& rGeometry, + const Point& rReferencePoint, + const std::size_t Component) + { + auto num_nodes = rGeometry.PointsNumber(); + if (rNodalDistances.size() != num_nodes) { + rNodalDistances.resize(num_nodes); + noalias(rNodalDistances) = ZeroVector(num_nodes); + } + + auto idistance = rNodalDistances.begin(); + const double reference_coord = rReferencePoint[Component]; + std::size_t points_over = 0; + + for (const auto& point: rGeometry) { + const double d = point[Component] - reference_coord; + if (d >= 0) points_over++; + *(idistance++) = d; + } + + return points_over; + } + + template + static std::vector TrimHigher( + const std::vector& rGeometries, + const Point& rLowPoint, + std::size_t Component) + { + using PointType = typename GeometryType::PointType; + std::vector cut, trimmed_geometries; + Vector nodal_distances; + + for (auto iter = rGeometries.begin(); iter < rGeometries.end(); ++iter) { + auto& r_geom = **iter; + cut.resize(0); + + std::size_t points_under = SignedDistanceUnder(nodal_distances, r_geom, rLowPoint, Component); + if (points_under == 3) { + trimmed_geometries.push_back(*iter); + } + else if (points_under > 0) { + auto splitter = DivideTriangle3D3(r_geom, nodal_distances); + splitter.GenerateDivision(); + cut = splitter.GetPositiveSubdivisions(); + trimmed_geometries.insert(trimmed_geometries.end(), cut.begin(), cut.end()); + } + } + + return trimmed_geometries; + } + + template + static std::vector TrimLower( + const std::vector& rGeometries, + const Point& rHighPoint, + std::size_t Component) + { + using PointType = typename GeometryType::PointType; + std::vector cut, trimmed_geometries; + Vector nodal_distances; + + for (auto iter = rGeometries.begin(); iter < rGeometries.end(); ++iter) { + auto& r_geom = **iter; + cut.resize(0); + + std::size_t points_over = SignedDistanceOver(nodal_distances, r_geom, rHighPoint, Component); + if (points_over == 3) { + trimmed_geometries.push_back(*iter); + } + else if (points_over > 0) { + auto splitter = DivideTriangle3D3(r_geom, nodal_distances); + splitter.GenerateDivision(); + cut = splitter.GetPositiveSubdivisions(); + trimmed_geometries.insert(trimmed_geometries.end(), cut.begin(), cut.end()); + } + } + + return trimmed_geometries; + } + + // Each component of rIntegrationPointData is a 4-component vector + // Components 0-2 are the GLOBAL coordinates of the integration point + // Component 3 is the integration point weight in terms of area (DetJ*Gauss_W) + void AddTriangleIntegrationPointData( + std::vector& rIntegrationPointData, + const SplitGeometryType& rGeom, + const GeometryData::IntegrationMethod Method) const + { + const std::size_t num_nodes = rGeom.PointsNumber(); + const auto& r_integration_points = rGeom.IntegrationPoints(Method); + const std::size_t num_gauss = r_integration_points.size(); + std::size_t new_point_offset = rIntegrationPointData.size(); + + Matrix shape_functions = rGeom.ShapeFunctionsValues(Method); + Vector det_j; + rGeom.DeterminantOfJacobian(det_j, Method); + + for (std::size_t g = 0; g < num_gauss; g++) { + Vector data = ZeroVector(4); + data[3] = r_integration_points[g].Weight() * det_j[g]; + rIntegrationPointData.push_back(data); + } + + for (std::size_t n = 0; n < num_nodes; n++) { + const auto& r_coordinates = rGeom[n].Coordinates(); + for (std::size_t g = 0; g < num_gauss; g++) { + for (std::size_t d = 0; d < 3; d++) { + rIntegrationPointData[new_point_offset+g][d] += shape_functions(g, n)*r_coordinates[d]; + } + } + } + } + + bool PointIsOnSharedFace(Vector& rPointData, std::size_t i, std::size_t j, std::size_t k) const + { + constexpr double coordinate_tol = 1e-9; + if (std::abs(rPointData[0] + 1.0) < coordinate_tol && i != 0) return true; + if (std::abs(rPointData[0] - 1.0) < coordinate_tol && i != mNumDivisions[0]) return true; + if (std::abs(rPointData[1] + 1.0) < coordinate_tol && j != 0) return true; + if (std::abs(rPointData[1] - 1.0) < coordinate_tol && j != mNumDivisions[1]) return true; + if (std::abs(rPointData[2] + 1.0) < coordinate_tol && k != 0) return true; + if (std::abs(rPointData[2] - 1.0) < coordinate_tol && k != mNumDivisions[1]) return true; + return false; + } + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/internals/voxel_mesher_component_factory.h b/kratos/modeler/internals/voxel_mesher_component_factory.h new file mode 100644 index 000000000000..60b49e1e4050 --- /dev/null +++ b/kratos/modeler/internals/voxel_mesher_component_factory.h @@ -0,0 +1,88 @@ + +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Jordi Cotela +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "factories/factory.h" +#include "includes/kratos_components.h" +#include "includes/kratos_parameters.h" + +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos { + +namespace Internals { + + template + class BaseRegisteredComponent { + public: + using BaseComponentType = BaseType; + explicit BaseRegisteredComponent() {} + virtual ~BaseRegisteredComponent() = default; + virtual typename BaseType::Pointer Create(VoxelMeshGeneratorModeler& rModeler, Parameters Settings) const = 0; + }; + + template + class RegisteredComponent: public BaseRegisteredComponent { + public: + explicit RegisteredComponent() {} + ~RegisteredComponent() override = default; + typename BaseType::Pointer Create(VoxelMeshGeneratorModeler& rModeler, Parameters Settings) const override + { + return Kratos::make_shared(rModeler, Settings); + } + }; + +} + +template +class VoxelMesherComponentFactory: public FactoryBase { + std::string mName; +public: + using RegisteredType = Internals::BaseRegisteredComponent; + + explicit VoxelMesherComponentFactory(): mName("voxel mesher component") {}; + + explicit VoxelMesherComponentFactory(const std::string& rName): mName(rName) {}; + + ~VoxelMesherComponentFactory() override = default; + + bool Has(const std::string& rComponentName) const override + { + return KratosComponents::Has(rComponentName); + } + + typename ComponentType::Pointer Create(VoxelMeshGeneratorModeler& rModeler, Parameters Settings) const + { + const auto type = Settings["type"].GetString(); + KRATOS_ERROR_IF_NOT(Has(type)) + << "Trying to construct " << mName << " with unregistered type \"" << type << "\"" << std::endl + << "The list of available options are: " << std::endl + << KratosComponents() << std::endl; + return KratosComponents::Get(type).Create(rModeler, Settings); + } + + template + static void Register(const std::string& rName) { + static const Internals::RegisteredComponent component{}; + KratosComponents::Add(rName, component); + } + +}; + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation.cpp b/kratos/modeler/key_plane_generation/key_plane_generation.cpp new file mode 100644 index 000000000000..216308dbb911 --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation.cpp @@ -0,0 +1,64 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation.h" + +namespace Kratos { + +VoxelMesherKeyPlaneGeneration::VoxelMesherKeyPlaneGeneration(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + mrModeler(rModeler), + mParameters(GenerationParameters) +{} + + +void VoxelMesherKeyPlaneGeneration::ValidateParameters() +{ + mParameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); +} + + +Parameters VoxelMesherKeyPlaneGeneration::GetParameters() const +{ + return mParameters; +} + + +Parameters VoxelMesherKeyPlaneGeneration::GetDefaultParameters() const +{ + return Parameters(R"({ + "voxel_sizes": [], + "min_point": [], + "max_point": [] + })"); +} + + +void VoxelMesherKeyPlaneGeneration::AddKeyPlane(std::size_t Direction, double Coordinate) +{ + mrModeler.mKeyPlanes[Direction].push_back(Coordinate); +} + + +const ModelPart& VoxelMesherKeyPlaneGeneration::GetInputModelPart() const { + return *(mrModeler.mpInputModelPart); +} + +const ModelPart& VoxelMesherKeyPlaneGeneration::GetModelPart(const std::string& rMyModelPart) const { + return mrModeler.CreateAndGetModelPart(rMyModelPart); +} + +} \ No newline at end of file diff --git a/kratos/modeler/key_plane_generation/key_plane_generation.h b/kratos/modeler/key_plane_generation/key_plane_generation.h new file mode 100644 index 000000000000..00aa8c38e6ab --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation.h @@ -0,0 +1,58 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/kratos_parameters.h" +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos { + +class KRATOS_API(KRATOS_CORE) VoxelMesherKeyPlaneGeneration { + + VoxelMeshGeneratorModeler& mrModeler; + Parameters mParameters; + +public: + + KRATOS_CLASS_POINTER_DEFINITION(VoxelMesherKeyPlaneGeneration); + + VoxelMesherKeyPlaneGeneration(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters); + + virtual ~VoxelMesherKeyPlaneGeneration() = default; + + virtual void ValidateParameters(); + + virtual void Generate() = 0; + +protected: + + Parameters GetParameters() const; + + virtual Parameters GetDefaultParameters() const; + + // internal interface to VoxelMeshGeneratorModeler + + void AddKeyPlane(std::size_t Direction, double Coordinate); + + const ModelPart& GetInputModelPart() const; + + const ModelPart& GetModelPart(const std::string& rMyName) const; + +}; + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.cpp b/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.cpp new file mode 100644 index 000000000000..eb5ea0531210 --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.cpp @@ -0,0 +1,69 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation_by_bounding_box.h" + +namespace Kratos { + +void KeyPlaneGenerationByBoundingBox::ValidateParameters() +{ + KRATOS_TRY; + Parameters parameters = this->GetParameters(); + parameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); + + KRATOS_ERROR_IF(parameters["voxel_sizes"].size() != 3) << "voxel_sizes should be defined for this generator as an array of 3 sizes for x,y,z directions" << std::endl; + KRATOS_ERROR_IF(parameters["min_point"].size() != 3) << "min_point should be defined for this generator as an array of 3 coordinates of the min point" << std::endl; + KRATOS_ERROR_IF(parameters["max_point"].size() != 3) << "max_point should be defined for this generator as an array of 3 coordinates of the max point" << std::endl; + + KRATOS_CATCH(""); +} + +void KeyPlaneGenerationByBoundingBox::Generate() +{ + Parameters parameters = GetParameters(); + Generate(parameters); +} + +void KeyPlaneGenerationByBoundingBox::Generate(Parameters parameters) +{ + array_1d voxel_sizes = parameters["voxel_sizes"].GetVector(); + array_1d min_point = parameters["min_point"].GetVector(); + array_1d max_point = parameters["max_point"].GetVector(); + + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + double input_voxel_size = voxel_sizes[i_direction]; + const double min_coordinate = min_point[i_direction]; + const double max_coordinate = max_point[i_direction]; + + KRATOS_ERROR_IF(input_voxel_size == 0.00) << "voxel_sizes in direction " << i_direction << " cannot be 0.00"; + + const double length = (max_coordinate - min_coordinate); + + KRATOS_ERROR_IF_NOT(length>0.0) << "Negative or zero length of voxelization bounding box in " << i_direction << " direction" << std::endl; + + std::size_t number_of_divisions = static_cast(std::round(length / input_voxel_size)); + number_of_divisions= (number_of_divisions == 0) ? 1 : number_of_divisions; + + const double voxel_size = length / number_of_divisions; + + for( std::size_t i = 0 ; i < number_of_divisions + 1 ; i++){ + AddKeyPlane(i_direction, min_coordinate + i*voxel_size); + } + } +} + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.h b/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.h new file mode 100644 index 000000000000..961b4cd0b07a --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_by_bounding_box.h @@ -0,0 +1,47 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation.h" + +namespace Kratos { + +/// Creates the key planes positions in x,y,z directions +/** It takes the min_point and max_point of the bounding box and + * divides each direction into uniform divisions with length as + * close as possible to the given size. + */ +class KeyPlaneGenerationByBoundingBox: public VoxelMesherKeyPlaneGeneration { +public: + KeyPlaneGenerationByBoundingBox(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherKeyPlaneGeneration(rModeler, GenerationParameters) + {} + + ~KeyPlaneGenerationByBoundingBox() override = default; + + void ValidateParameters() override; + + void Generate() override; + +protected: + + virtual void Generate(Parameters parameters); + +}; + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_by_outer_shell.h b/kratos/modeler/key_plane_generation/key_plane_generation_by_outer_shell.h new file mode 100644 index 000000000000..ca7fd69349ff --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_by_outer_shell.h @@ -0,0 +1,77 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation_by_bounding_box.h" + +namespace Kratos { + +class KeyPlaneGenerationByOuterShell: public KeyPlaneGenerationByBoundingBox { +public: + KeyPlaneGenerationByOuterShell(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + KeyPlaneGenerationByBoundingBox(rModeler, GenerationParameters) + {} + + ~KeyPlaneGenerationByOuterShell() override = default; + + void ValidateParameters() override + { + KRATOS_TRY; + Parameters parameters = this->GetParameters(); + parameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); + + KRATOS_ERROR_IF(parameters["voxel_sizes"].size() != 3) << "voxel_sizes should be defined for this generator as an array of 3 sizes for x,y,z directions" << std::endl; + + KRATOS_CATCH(""); + } + + void Generate() override + { + Parameters parameters = this->GetParameters(); + Parameters bounding_box_parameters = parameters.Clone(); + + auto dx = parameters["voxel_sizes"].GetVector(); + // Now we find the min and max value for the node coordinates + Vector min_v(3,std::numeric_limits::max()), max_v(3, -std::numeric_limits::max()); + for(auto& node: GetInputModelPart().Nodes()){ + double x = node.X(), y = node.Y(), z = node.Z(); + min_v[0] = std::min(min_v[0], x); max_v[0] = std::max(max_v[0], x); + min_v[1] = std::min(min_v[1], y); max_v[1] = std::max(max_v[1], y); + min_v[2] = std::min(min_v[2], z); max_v[2] = std::max(max_v[2], z); + } + // Now we fill the PP and complete it + double epsilon = parameters["margin"].GetDouble(); + bounding_box_parameters.AddVector("min_point", min_v - ((1.0 + epsilon)*dx)); + bounding_box_parameters.AddVector("max_point", max_v + ((1.0 + epsilon)*dx)); + + KeyPlaneGenerationByBoundingBox::Generate(bounding_box_parameters); + } + +protected: + + Parameters GetDefaultParameters() const override + { + return Parameters(R"({ + "voxel_sizes": [], + "margin": 0.01 + })"); + } + +}; + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_factory.cpp b/kratos/modeler/key_plane_generation/key_plane_generation_factory.cpp new file mode 100644 index 000000000000..5bfc802882be --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_factory.cpp @@ -0,0 +1,58 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation_factory.h" +#include "key_plane_generation_by_bounding_box.h" +#include "key_plane_generation_by_outer_shell.h" +#include "key_plane_generation_with_refinement.h" + +namespace Kratos { + +VoxelMesherKeyPlaneGeneration::Pointer KeyPlaneGenerationFactory::Create( + VoxelMeshGeneratorModeler& rModeler, + Parameters GenerationSettings) const +{ + KRATOS_TRY; + + if (GenerationSettings.Has("type") && !GenerationSettings["type"].IsString()) { + KRATOS_ERROR << "Voxel mesh generation modeler key plane factory error: \"type\" must be a string" << std::endl; + } + KRATOS_ERROR_IF_NOT(GenerationSettings.Has("Parameters")) + << "Voxel mesh generation modeler key plane factory error: \"Parameters\" argument is required" << std::endl; + + const std::string type = GenerationSettings.Has("type") ? GenerationSettings["type"].GetString() : "bounding_box"; + KRATOS_ERROR_IF_NOT(Has(type)) + << "Trying to construct key plane generation strategy with unregistered type \"" << type << "\"" << std::endl + << "The list of available options are: " << std::endl + << KratosComponents() << std::endl; + + return KratosComponents::Get(type).Create(rModeler, GenerationSettings["Parameters"]); + + KRATOS_CATCH(""); +} + +template class KratosComponents; + + +void RegisterVoxelMesherKeyPlaneGeneration() +{ + KeyPlaneGenerationFactory::Register("bounding_box"); + KeyPlaneGenerationFactory::Register("outer_shell"); + KeyPlaneGenerationFactory::Register("outer_shell_with_refinement"); +} + +} \ No newline at end of file diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_factory.h b/kratos/modeler/key_plane_generation/key_plane_generation_factory.h new file mode 100644 index 000000000000..83e3bb5074a4 --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_factory.h @@ -0,0 +1,35 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "modeler/internals/voxel_mesher_component_factory.h" +#include "key_plane_generation.h" + +namespace Kratos { + +class KeyPlaneGenerationFactory: public VoxelMesherComponentFactory { +public: + VoxelMesherKeyPlaneGeneration::Pointer Create(VoxelMeshGeneratorModeler& rModeler, Parameters ColoringSettings) const; + +}; + +KRATOS_API_EXTERN template class KRATOS_API(KRATOS_CORE) KratosComponents; + +void RegisterVoxelMesherKeyPlaneGeneration(); + +} \ No newline at end of file diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.cpp b/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.cpp new file mode 100644 index 000000000000..21c584bb2215 --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.cpp @@ -0,0 +1,250 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation_with_refinement.h" + +namespace Kratos { +typedef std::pair, array_1d> BoundingBoxType; +void KeyPlaneGenerationWithRefinement::ValidateParameters() +{ + KRATOS_TRY; + Parameters parameters = this->GetParameters(); + parameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); + KRATOS_ERROR_IF(parameters["voxel_sizes"].size() != 3) << "voxel_sizes should be defined for this generator as an array of 3 sizes for x,y,z directions" << std::endl; + if(parameters["refinement_zones"].size()!=0){ + for(auto refinement_parameters : parameters["refinement_zones"]){ + refinement_parameters.ValidateAndAssignDefaults(this->GetDefaultRefinementZoneParameters()); + KRATOS_ERROR_IF(refinement_parameters["refined_modelpart"].GetString() == "" && IsEmpty(refinement_parameters["refined_zone"])) << "Refinement zones must be specified either as custom coordinates or as a model part bounding box. Both of them are empty" << std::endl; + KRATOS_ERROR_IF(refinement_parameters["refined_modelpart"].GetString() != "" && !IsEmpty(refinement_parameters["refined_zone"])) << "Refinement zones must be specified either as custom coordinates or as a model part bounding box. Both of them are specified" << std::endl; + refinement_parameters["refined_zone"].ValidateAndAssignDefaults(GetDefaultRefinementZoneParameters()["refined_zone"]); + KRATOS_ERROR_IF(refinement_parameters["voxel_sizes_ratio"].size() != 3) << "voxel_sizes_ratio should be defined for this generator as an array of 3 scale factors for x,y,z directions" << std::endl; + } + } + KRATOS_CATCH(""); +} + +void KeyPlaneGenerationWithRefinement::Generate() +{ + // First we compute the bounding box. It uses the same as outer shell + Parameters parameters = this->GetParameters(); + array_1d dx = parameters["voxel_sizes"].GetVector(); + BoundingBoxType global_bounding_box = GetBoundingBox(this->GetInputModelPart()); + array_1d global_voxel_size = dx; + //Now we go for the refinament areas. + std::vector refinament_areas; + std::vector> voxel_sizes; + FindRefinements(refinament_areas, voxel_sizes, global_voxel_size); // This reads the Paramters and store the data in the appropiate structure + std::pair,3>,array_1d,3>> partitions_and_voxels = ComputePartitionsAndVoxelSizeByDirection(refinament_areas, voxel_sizes, global_bounding_box, global_voxel_size); + array_1d,3>& r_partitions = partitions_and_voxels.first; + array_1d,3>& r_partitions_division_size = partitions_and_voxels.second; + GenerateKeyplanes(r_partitions, r_partitions_division_size); +} + +Parameters KeyPlaneGenerationWithRefinement::GetDefaultParameters() const +{ + return Parameters(R"({ + "refinement_zones":[], + "voxel_sizes": [], + "margin": 0.01 + })"); +} + +Parameters KeyPlaneGenerationWithRefinement::GetDefaultRefinementZoneParameters() +{ + return Parameters(R"({ + "refined_modelpart" : "", + "refined_zone" : { + "min_point" : [0.0, 0.0, 0.0], + "max_point" : [1.0 , 1.0, 1.0] + }, + "voxel_sizes_ratio": [] + })"); +} + +BoundingBoxType KeyPlaneGenerationWithRefinement::GetBoundingBox(const ModelPart& rMyModelPart) +{ + // Now we find the min and max value for the node coordinates + array_1d min_v(3,std::numeric_limits::max()), max_v(3, -std::numeric_limits::max()); + // Find Bounding box + for(auto& r_node : rMyModelPart.Nodes()){ + double x = r_node.X(), y = r_node.Y(), z = r_node.Z(); + min_v[0] = std::min(min_v[0], x); max_v[0] = std::max(max_v[0], x); + min_v[1] = std::min(min_v[1], y); max_v[1] = std::max(max_v[1], y); + min_v[2] = std::min(min_v[2], z); max_v[2] = std::max(max_v[2], z); + } + return std::make_pair(min_v, max_v); +} +bool KeyPlaneGenerationWithRefinement::IsEmpty(Parameters param) +{ + return param.WriteJsonString() == "{}"; +} + +void KeyPlaneGenerationWithRefinement::FindRefinements(std::vector& rRefinementAreas, std::vector>& rVoxelSizes,const array_1d& rGlobalVoxelSize){ + Parameters parameters = this->GetParameters(); + for(auto refinement_parameters : parameters["refinement_zones"]){ + // Now we either select the given refinement zone or compute it using a modelpart + BoundingBoxType refinement_zone; + if(refinement_parameters["refined_modelpart"].GetString() != ""){ // ModelParts are not empty and we are going to find the bounding box + const ModelPart& r_refined_modelpart = GetModelPart(refinement_parameters["refined_modelpart"].GetString()); + if(r_refined_modelpart.NumberOfNodes() > 0) { + refinement_zone = GetBoundingBox(r_refined_modelpart); + rRefinementAreas.push_back(refinement_zone); + } + } else { + refinement_zone.first = refinement_parameters["refined_zone"]["min_point"].GetVector(); + refinement_zone.second = refinement_parameters["refined_zone"]["max_point"].GetVector(); + rRefinementAreas.push_back(refinement_zone); + //TODO avoid the refinament area to be defined outside the global bounding box + } + // Now we add the element size on each direction + array_1d dx_local = refinement_parameters["voxel_sizes_ratio"].GetVector(); + dx_local[0] *= rGlobalVoxelSize[0]; dx_local[1] *= rGlobalVoxelSize[1]; dx_local[2] *= rGlobalVoxelSize[2]; + rVoxelSizes.push_back(dx_local); + } +} + +std::pair,3>,array_1d,3>> KeyPlaneGenerationWithRefinement::ComputePartitionsAndVoxelSizeByDirection(std::vector& rRefinementAreas, + std::vector>& rVoxelSizes, + BoundingBoxType& rGlobalBoundingBox, + const array_1d& rGlobalVoxelSize){ + array_1d,3> partitions; + array_1d,3> partitions_voxel_sizes; + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + std::vector& r_i_partition = partitions[i_direction]; + // TODO: Adding reserve + r_i_partition.push_back(rGlobalBoundingBox.first[i_direction]); + r_i_partition.push_back(rGlobalBoundingBox.second[i_direction]); + for(auto& area: rRefinementAreas){ + r_i_partition.push_back(area.first[i_direction]); + r_i_partition.push_back(area.second[i_direction]); + } + // Now we sort the beginnig and ends and make them uniqe + std::sort(r_i_partition.begin(), r_i_partition.end()); + r_i_partition.erase(std::unique(r_i_partition.begin(), r_i_partition.end()), r_i_partition.end()); + // if there are more than 2, we loop in the inner ones and if they are too close we remove them + } + // Now we fill the proposed voxel size + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + std::vector& r_i_partitions_voxel_sizes = partitions_voxel_sizes[i_direction]; + std::vector& r_i_partition = partitions[i_direction]; + for (std::size_t i = 1; i < r_i_partition.size(); ++i) { + const double pos = 0.5*(r_i_partition[i-1] + r_i_partition[i]); + const double dx = ReturnLocalTheoreticalVoxelSize(rRefinementAreas, rVoxelSizes, rGlobalBoundingBox, rGlobalVoxelSize, i_direction, pos); + r_i_partitions_voxel_sizes.push_back(dx); + } + } + // Now we loop over the partitions and if 2 of them are too close we replace them for one in the middle + constexpr double K=0.1; + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + std::vector& r_i_partitions_voxel_sizes = partitions_voxel_sizes[i_direction]; + std::vector& r_i_partition = partitions[i_direction]; + bool keep_merging = true; + while(keep_merging) + { + std::vector new_i_partitions; + std::vector new_i_partitions_voxel_sizes; + // We add the first ones to the new partitions (leave the first point untouched) + new_i_partitions.push_back(*r_i_partition.begin()); + new_i_partitions_voxel_sizes.push_back(*r_i_partitions_voxel_sizes.begin()); + // Now we loop from the second one to the end and merge the ones in the middle + keep_merging = false; + if(r_i_partition.size()>3){ + // The first one and the last one cannot be removed or moved. + for (std::size_t i = 1; i+2 < r_i_partition.size(); ++i) { //This is to ensure we don't remove the last one nor the first one so i+1 is the end - 1 + const double l = std::abs(r_i_partition[i+1] - r_i_partition[i]); + const double theoretical_l = r_i_partitions_voxel_sizes[i]; + // If they are too close we are going to merge them + if(l<= theoretical_l*K){ // We avoid removing the final ones + // We merge them + const double pos = 0.5*(r_i_partition[i+1] + r_i_partition[i]); + KRATOS_INFO("Keyplane Merging") << "In direction: " << i_direction << " KeyPlanes: " <& rRefinementAreas, + std::vector>& rVoxelSizes, + BoundingBoxType& rGlobalBoundingBox, + const array_1d& rGlobalVoxelSize, + int Direction, + double Position){ + KRATOS_ERROR_IF(PositionrGlobalBoundingBox.second[Direction]) << "Trying to obtain the voxel size of a position outside the global bounding box." <,3>& rPartitionLimits, array_1d,3>& rTheoreticalVoxelSize) { + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + std::vector& r_i_partition = rPartitionLimits[i_direction]; + std::vector& r_i_voxel_size = rTheoreticalVoxelSize[i_direction]; + KRATOS_ERROR_IF(r_i_partition.size() != r_i_voxel_size.size()+1) << "Partitions and theoretical voxel size does not match " + << r_i_partition.size() <<"!=" << r_i_voxel_size.size()<<"+1" << std::endl; + AddKeyPlane(i_direction, r_i_partition.front() - r_i_voxel_size.front()); // We add a KeyPlane that corresponds to the Bounding box -dx so that later we don't have any issue finding contacts + for(std::size_t i = 0; i+1 < r_i_partition.size(); ++i){ // Last one will be added manually + double h = r_i_partition[i+1] - r_i_partition[i]; + double& r_theoretical_dx = r_i_voxel_size[i]; + std::size_t number_of_divisions = std::ceil(h/r_theoretical_dx); // so that the effective voxel size is smaller than dx + double dx = h/number_of_divisions; + for(std::size_t j=0; j KeyPlaneGenerationWithRefinement::ComputEffectiveVoxelSize(const array_1d& rMinCoordinate, + const array_1d& rMaxCoordinate, + const array_1d& rInputVoxelSize){ + array_1d voxel_size; + for(std::size_t i_direction = 0 ; i_direction < 3 ; i_direction++){ + const double length = (rMaxCoordinate[i_direction] - rMinCoordinate[i_direction]); + KRATOS_ERROR_IF_NOT(length>0.0) << "Negative or zero length of voxelization bounding box in " << i_direction << " direction" << std::endl; + std::size_t number_of_divisions = static_cast(std::round(length / rInputVoxelSize[i_direction])); + number_of_divisions= (number_of_divisions == 0) ? 1 : number_of_divisions; + voxel_size[i_direction] = length / number_of_divisions; + } + return voxel_size; +} + +} diff --git a/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.h b/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.h new file mode 100644 index 000000000000..355cab51cd11 --- /dev/null +++ b/kratos/modeler/key_plane_generation/key_plane_generation_with_refinement.h @@ -0,0 +1,142 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Jordi Rubio +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "key_plane_generation.h" + +namespace Kratos { + +struct RefinementZone +{ + array_1d MinPos; + array_1d MaxPos; + array_1d Dx; + + RefinementZone(const array_1d& rMinPos, const array_1d& rMaxPos, const array_1d& rDx): MinPos(rMinPos), MaxPos(rMaxPos), Dx(rDx) + {} +}; + +class KeyPlaneGenerationWithRefinement: public VoxelMesherKeyPlaneGeneration { + typedef std::pair, array_1d> BoundingBoxType; +public: + KeyPlaneGenerationWithRefinement(VoxelMeshGeneratorModeler& rModeler, Parameters GenerationParameters): + VoxelMesherKeyPlaneGeneration(rModeler, GenerationParameters) + {} + + ~KeyPlaneGenerationWithRefinement() override = default; + + void ValidateParameters() override; + + void Generate() override; + +protected: + + /** + * @brief Retrieves the default parameters for the current utility. + * @details This method provides a set of default parameters that can be used to initialize or reset the object's state. + * @return Parameters A Parameters object containing the default values. + */ + Parameters GetDefaultParameters() const override; + + /** + * @brief Retrieves the default parameters for the refinement zone. + * @details This method returns a set of parameters specifically tailored for controlling the behavior and properties of the refinement zone. + * @return Parameters A Parameters object with default settings for the refinement zone. + */ + Parameters GetDefaultRefinementZoneParameters(); + + /** + * @brief Calculates the bounding box for a given model part. + * details This method computes the bounding box that encloses the specified model part, which is useful for spatial queries and optimization tasks. + * @param rMyModelPart Reference to the ModelPart object for which the bounding box is to be calculated. + * @return BoundingBoxType The bounding box encapsulating the given model part. + */ + BoundingBoxType GetBoundingBox(const ModelPart& rMyModelPart); + + /** + * @brief Checks if the provided parameters object is empty. + * @details This method determines whether a given Parameters object lacks configuration or is considered empty. + * @param param The Parameters object to check. + * @return bool True if the Parameters object is empty; otherwise, false. + */ + bool IsEmpty(Parameters param); + + /** + * @brief Identifies refinement areas and calculates voxel sizes for each area. + * @details This method processes a list of refinement areas and their corresponding voxel sizes based on the global voxel size configuration. It helps in refining the mesh or grid structure in specific regions. + * @param rRefinementAreas Reference to a vector of BoundingBoxType that will be filled with the identified refinement areas. + * @param rVoxelSizes Reference to a vector of voxel sizes, one for each refinement area. + * @param rGlobalVoxelSize The global voxel size used as a reference for calculation. + */ + void FindRefinements(std::vector& rRefinementAreas, std::vector>& rVoxelSizes,const array_1d& rGlobalVoxelSize); + + /** + * @brief Computes partitions and voxel sizes by direction based on refinement areas. + * @details This method calculates the partitions and their respective voxel sizes in each direction, considering the provided refinement areas and voxel sizes. It's useful for adaptive mesh refinement. + * @param rRefinementAreas Reference to a vector of BoundingBoxType indicating the areas of refinement. + * @param rVoxelSizes Reference to a vector of voxel sizes for each refinement area. + * @param rGlobalBoundingBox The global bounding box within which the calculations are performed. + * @param rGlobalVoxelSize The global voxel size, serving as a baseline for calculations. + * @return A pair of array_1d objects, each containing vectors of doubles representing the partition limits and the theoretical voxel sizes in each direction. + */ + std::pair,3>,array_1d,3>> ComputePartitionsAndVoxelSizeByDirection(std::vector& rRefinementAreas, + std::vector>& rVoxelSizes, + BoundingBoxType& rGlobalBoundingBox, + const array_1d& rGlobalVoxelSize); + + /** + * @brief Returns the theoretical voxel size for a specific position and direction within the global bounding box. + * @details This method calculates the theoretical voxel size at a given position and direction, taking into account the refinement areas and their voxel sizes. + * @param rRefinementAreas Reference to a vector of BoundingBoxType indicating the areas of refinement. + * @param rVoxelSizes Reference to a vector of voxel sizes for each refinement area. + * @param rGlobalBoundingBox The global bounding box within which the calculations are performed. + * @param rGlobalVoxelSize The baseline global voxel size. + * @param Direction The direction in which the voxel size is calculated. + * @param Position The position at which the voxel size is calculated. + * @return double The calculated theoretical voxel + */ + double ReturnLocalTheoreticalVoxelSize(std::vector& rRefinementAreas, + std::vector>& rVoxelSizes, + BoundingBoxType& rGlobalBoundingBox, + const array_1d& rGlobalVoxelSize, + int Direction, + double Position); + + /** + * @brief Generates keyplanes based on partition limits and theoretical voxel sizes. + * @details This function is designed to process the partitioning of a computational domain into keyplanes based on the provided partition limits and the theoretical voxel sizes. Keyplanes are essential for optimizing spatial queries and data access in computational geometry and volume processing tasks. + * @param PartitionLimits An array of three std::vector elements representing the partition limits in each of the three dimensions (X, Y, Z). Each vector contains the boundary values that define the partitions in its respective dimension. + * @param TheoreticalVoxelSize An array of three std::vector elements representing the theoretical voxel sizes in each of the three dimensions (X, Y, Z). Each vector contains values that define the desired resolution of the voxels in its respective dimension. + */ + void GenerateKeyplanes(array_1d,3>& rPartitionLimits, array_1d,3>& rTheoreticalVoxelSize); + + /** + * @brief Computes the effective voxel size given the minimum and maximum coordinates of a region and the input voxel size. + * The effective voxel size is calculated to fit within the specified region defined by minimum and maximum coordinates while adhering to the input voxel size as closely as possible. This calculation is crucial for adjusting the resolution of a discretized space to match specific computational requirements. + * @param rMinCoordinate An array_1d representing the minimum coordinates (Xmin, Ymin, Zmin) of the region for which the effective voxel size is being computed. + * @param rMaxCoordinate An array_id representing the maximum coordinates (Xmax, Ymax, Zmax) of the region for which the effective voxel size is being computed. + * @param rInputVoxelSize An array_id representing the initial voxel size (Xsize, Ysize, Zsize) as input for the computation. + * @return array_1d representing the effective voxel size (Xeff, Yeff, Zeff) that best fits within the specified region while considering the input voxel size. + */ + array_1d ComputEffectiveVoxelSize(const array_1d& rMinCoordinate, + const array_1d& rMaxCoordinate, + const array_1d& rInputVoxelSize); + +}; + +} diff --git a/kratos/modeler/operation/find_contacts_in_skin_model_part.cpp b/kratos/modeler/operation/find_contacts_in_skin_model_part.cpp new file mode 100644 index 000000000000..ad52b3e22c41 --- /dev/null +++ b/kratos/modeler/operation/find_contacts_in_skin_model_part.cpp @@ -0,0 +1,249 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "utilities/parallel_utilities.h" +#include "find_contacts_in_skin_model_part.h" + +namespace Kratos { + +Parameters FindContactsInSkinModelPart::GetDefaultParameters() const +{ + return Parameters(R"({ + "type" : "find_contacts_in_skin_model_part", + "model_part_name": "Undefined", + "contact_model_parts" : [], + "cell_color": -1 + })"); +} + +void FindContactsInSkinModelPart::ValidateParameters() +{ + Parameters parameters = GetParameters(); + parameters.ValidateAndAssignDefaults(GetDefaultParameters()); + + Parameters contact_default_parameters(R"({ + "outside_color": -1, + "contact_model_part_name": "Undefined" + })"); + for (auto contact_parameters : parameters["contact_model_parts"]) { + contact_parameters.ValidateAndAssignDefaults(contact_default_parameters); + } +} + +void FindContactsInSkinModelPart::Apply() const +{ + ContactContainer contact_container; + Parameters parameters = GetParameters(); + + for (auto contact_parameters : parameters["contact_model_parts"]) { + const int outside_color = contact_parameters["outside_color"].GetInt(); + ModelPart& r_model_part = CreateAndGetModelPart( + contact_parameters["contact_model_part_name"].GetString()); + + contact_container.mNodeMap.insert(std::make_pair(outside_color, std::vector())); + contact_container.mConditionsMap.insert(std::make_pair(outside_color, std::vector())); + contact_container.mModelPartMap.insert(std::make_pair(outside_color, &r_model_part)); + contact_container.mColorVector.push_back(outside_color); + } + + ModelPart& r_skin_part = GetModelPart(parameters["model_part_name"].GetString()); + const int cell_color = parameters["cell_color"].GetInt(); + KRATOS_INFO("Modeler") << "Finding contacts for " << r_skin_part.FullName() << " model part" << std::endl; + + block_for_each(r_skin_part.Conditions(),[&](Condition& rCondition) { + FindConditionContact( + rCondition, + cell_color, + contact_container); + }); + for (const auto color : contact_container.mColorVector) { + ModelPart& r_model_part = *(contact_container.mModelPartMap[color]); + r_model_part.AddConditions(contact_container.mConditionsMap[color]); + r_model_part.AddNodes(contact_container.mNodeMap[color]); + } + +} + +void FindContactsInSkinModelPart::FindConditionContact( + Condition& rCondition, + const int CellColor, + ContactContainer& rContactContainer) const +{ + // For each condition, we find the voxels that intersect with them + // and see if there is neighbour voxel with the required colour. + // We priorize the one that is closer to the condition and in the direction the normal is pointing + // We give priority to components that are connected to the voxel by faces + // (pairing status = 1) and then to components that are connected by a corner. + // (pairing status = 2). In both cases if we find different components we give + // priority to the components that are last on the list. + int pairing_status = 0; // 0=no_contact, 1=contact_by_corner, 2=contact_by_face + int temporary_color = 0; + double min_distance = std::numeric_limits::max(); + auto condition_center = rCondition.GetGeometry().Center(); + auto condition_normal = rCondition.GetGeometry().UnitNormal(condition_center); + array_1d min_position(3,0); + array_1d max_position(3,0); + std::vector face_neigh_colors; + face_neigh_colors.reserve(6); + std::vector all_neigh_colors; + all_neigh_colors.reserve(26); + const CartesianMeshColors& r_colors = GetMeshColors(); + r_colors.CalculateOuterMinMaxNodePositions(rCondition.GetGeometry(), min_position, max_position); + for(std::size_t k = min_position[2] ; k < max_position[2] ; k++){ + for(std::size_t j = min_position[1] ; j < max_position[1] ; j++){ + for(std::size_t i = min_position[0] ; i < max_position[0] ; i++){ + Point cell_min_point = r_colors.GetPoint(i,j,k); + Point cell_max_point = r_colors.GetPoint(i+1,j+1,k+1); + const int current_cell_color = std::lround(r_colors.GetElementalColor(i,j,k)); + if (current_cell_color == CellColor && + rCondition.GetGeometry().HasIntersection(cell_min_point,cell_max_point)) + { + //This cell intersects with condition and has correct color + const array_1d indexes{i,j,k}; + std::vector> face_neigh_indexes; + GetCellNeihgbourColorsConnectedByFace(indexes, r_colors, face_neigh_colors, face_neigh_indexes); + + // We check if there is any neighbour that satisfies: + // is connected by face, projection is within certain angle, distance + // to condition is minimum. + GetClosestContactColorFromNeighbours( + rContactContainer.mColorVector, + face_neigh_colors, + face_neigh_indexes, + condition_center, + condition_normal, + r_colors, + pairing_status, + min_distance, + temporary_color); + + // if not contact by face has been found we look for contacts by corner. + if (pairing_status < 2) { + const array_1d indexes{i,j,k}; + GetCellNeihgbourColors(indexes,all_neigh_colors, r_colors); + for (const auto& contact_color : rContactContainer.mColorVector) { + if (std::find(all_neigh_colors.begin(), all_neigh_colors.end(),contact_color) != all_neigh_colors.end()) { + pairing_status = 1; + temporary_color = contact_color; + break; + } + } + } + } + } + } + } + if (pairing_status > 0) { + //We did find a temporary candidate , so we use this one + KRATOS_CRITICAL_SECTION + { + rContactContainer.mConditionsMap[temporary_color].push_back(rCondition.Id()); + for (const auto& r_node : rCondition.GetGeometry()) { + rContactContainer.mNodeMap[temporary_color].push_back(r_node.Id()); + } + } + } +} + +void FindContactsInSkinModelPart::GetClosestContactColorFromNeighbours( + const std::vector& rContactColors, + const std::vector& rNeighbourColors, + const std::vector>& rNeighbourIndexes, + const array_1d& rConditionCenter, + const array_1d& rConditionNormal, + const CartesianMeshColors& rColors, + int& rPairingStatus, + double& rMinDistance, + int& rTemporaryColor) const +{ + constexpr double angle_threshold = 0.3; + auto neighbor_colors_iterator = rNeighbourColors.begin(); + for(auto& ind: rNeighbourIndexes){ + auto cell_center = rColors.GetCenterOfElement(ind[0], ind[1], ind[2]); + const int neigh_color = *(neighbor_colors_iterator++); + array_1d dist = cell_center - rConditionCenter; + double dist_modulus = norm_2(dist); + array_1d unit_dist; + if(dist_modulus > 1e-9) { + unit_dist = dist/dist_modulus; + } + const double projection = inner_prod(unit_dist, rConditionNormal); + bool color_is_contact = std::find( + rContactColors.begin(), + rContactColors.end(), neigh_color) != rContactColors.end(); + + if(color_is_contact && + projection > angle_threshold && + dist_modulus < rMinDistance) { + rPairingStatus = 2; + rMinDistance = dist_modulus; + rTemporaryColor = neigh_color; + } + } +} + +void FindContactsInSkinModelPart::GetCellNeihgbourColors( + const array_1d& rCellIndexes, + std::vector& rNeighbourColors, + const CartesianMeshColors& rColors) const +{ + rNeighbourColors.clear(); + int i_tmp,j_tmp,k_tmp; + for (int i = -1; i < 2; i++) { + i_tmp = rCellIndexes[0]+i; + for (int j = -1; j < 2; j++) { + j_tmp = rCellIndexes[1]+j; + for (int k = -1; k < 2; k++) { + k_tmp = rCellIndexes[2]+k; + if (!(i == 0 && j == 0 && k == 0) && IsElementInsideBounds(rColors, i_tmp, j_tmp, k_tmp)) { + rNeighbourColors.push_back(std::lround(rColors.GetElementalColor(i_tmp, j_tmp, k_tmp))); + } + } + } + } +} + +void FindContactsInSkinModelPart::GetCellNeihgbourColorsConnectedByFace( + const array_1d& rCellIndexes, + const CartesianMeshColors& rColors, + std::vector& rNeighbourColors, + std::vector>& rNeighbourIndexes) const +{ + rNeighbourColors.clear(); + rNeighbourIndexes.clear(); + array_1d i{-1,1,0,0,0,0}; + array_1d j{0,0,-1,1,0,0}; + array_1d k{0,0,0,0,-1,1}; + for (int idx = 0; idx < 6; idx++) { + int i_tmp = rCellIndexes[0]+i[idx]; + int j_tmp = rCellIndexes[1]+j[idx]; + int k_tmp = rCellIndexes[2]+k[idx]; + if(IsElementInsideBounds(rColors, i_tmp, j_tmp, k_tmp)){ + array_1d indexes{ static_cast(i_tmp), static_cast(j_tmp), static_cast(k_tmp)}; + double mtmp_color = rColors.GetElementalColor(i_tmp, j_tmp, k_tmp); + rNeighbourColors.push_back(std::lround(mtmp_color)); + rNeighbourIndexes.push_back(indexes); + } + } +} + +bool FindContactsInSkinModelPart::IsElementInsideBounds(const CartesianMeshColors& rColors, int i, int j, int k) const { + array_1d bounds = rColors.GetGridSize(); + return ((i=0 && j>=0 && k>=0); +} + +} \ No newline at end of file diff --git a/kratos/modeler/operation/find_contacts_in_skin_model_part.h b/kratos/modeler/operation/find_contacts_in_skin_model_part.h new file mode 100644 index 000000000000..f2df49dad8ee --- /dev/null +++ b/kratos/modeler/operation/find_contacts_in_skin_model_part.h @@ -0,0 +1,80 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/model_part.h" +#include "voxel_mesher_operation.h" + +namespace Kratos { + +class FindContactsInSkinModelPart: public VoxelMesherOperation { + + struct ContactContainer + { + std::unordered_map> mNodeMap; + std::unordered_map> mConditionsMap; + std::unordered_map mModelPartMap; + std::vector mColorVector; + }; + +public: + FindContactsInSkinModelPart(VoxelMeshGeneratorModeler& rModeler, Parameters OperationParameters): + VoxelMesherOperation(rModeler, OperationParameters) + {} + + ~FindContactsInSkinModelPart() override = default; + + Parameters GetDefaultParameters() const override; + + void ValidateParameters() override; + + void Apply() const override; + + void FindConditionContact( + Condition& rCondition, + const int CellColor, + ContactContainer& rContactContainer) const; + + void GetClosestContactColorFromNeighbours( + const std::vector& rContactColors, + const std::vector& rNeighbourColors, + const std::vector>& rNeighbourIndexes, + const array_1d& rConditionCenter, + const array_1d& rConditionNormal, + const CartesianMeshColors& rColors, + int& rPairingStatus, + double& rMinDistance, + int& rTemporaryColor) const; + + void GetCellNeihgbourColors( + const array_1d& rCellIndexes, + std::vector& rNeighbourColors, + const CartesianMeshColors& rColors) const; + + void GetCellNeihgbourColorsConnectedByFace( + const array_1d& rCellIndexes, + const CartesianMeshColors& rColors, + std::vector& rNeighbourColors, + std::vector>& rNeighbourIndexes) const; + + + bool IsElementInsideBounds(const CartesianMeshColors& rColors, int i, int j, int k) const; + +}; + +} \ No newline at end of file diff --git a/kratos/modeler/operation/voxel_mesher_operation.cpp b/kratos/modeler/operation/voxel_mesher_operation.cpp new file mode 100644 index 000000000000..903908d5067c --- /dev/null +++ b/kratos/modeler/operation/voxel_mesher_operation.cpp @@ -0,0 +1,69 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_operation.h" + +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos { + +VoxelMesherOperation::VoxelMesherOperation(VoxelMeshGeneratorModeler& rModeler, Parameters OperationParameters): + mrModeler(rModeler), + mParameters(OperationParameters) +{} + + +void VoxelMesherOperation::ValidateParameters() +{ + mParameters.ValidateAndAssignDefaults(this->GetDefaultParameters()); +} + + +Parameters VoxelMesherOperation::GetParameters() const +{ + return mParameters; +} + + +Parameters VoxelMesherOperation::GetDefaultParameters() const +{ + return Parameters(R"({})"); +} + + +ModelPart& VoxelMesherOperation::GetModelPart(const std::string& rName) const { + return mrModeler.mpModel->GetModelPart(rName); +} + + +ModelPart& VoxelMesherOperation::CreateAndGetModelPart(std::string const& rFullName) const { + return mrModeler.CreateAndGetModelPart(rFullName); +} + + +const VoxelMesherOperation::CartesianMeshColors& VoxelMesherOperation::GetMeshColors() const +{ + return mrModeler.mColors; +} + + +std::size_t VoxelMesherOperation::CalculateCenterOfElementPosition(double Coordinate, int ThisDimension) const +{ + return mrModeler.mColors.CalculateCenterOfElementPosition(Coordinate, ThisDimension); +} + +} \ No newline at end of file diff --git a/kratos/modeler/operation/voxel_mesher_operation.h b/kratos/modeler/operation/voxel_mesher_operation.h new file mode 100644 index 000000000000..5c025472eddc --- /dev/null +++ b/kratos/modeler/operation/voxel_mesher_operation.h @@ -0,0 +1,64 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/kratos_parameters.h" + +#include "modeler/voxel_mesh_generator_modeler.h" +#include "modeler/internals/cartesian_mesh_colors.h" + +namespace Kratos { + +class KRATOS_API(KRATOS_CORE) VoxelMesherOperation { + + VoxelMeshGeneratorModeler& mrModeler; + Parameters mParameters; + +public: + + using CartesianMeshColors = Internals::CartesianMeshColors; + + KRATOS_CLASS_POINTER_DEFINITION(VoxelMesherOperation); + + VoxelMesherOperation(VoxelMeshGeneratorModeler& rModeler, Parameters OperationParameters); + + virtual ~VoxelMesherOperation() = default; + + virtual void ValidateParameters(); + + virtual void Apply() const = 0; + +protected: + + Parameters GetParameters() const; + + virtual Parameters GetDefaultParameters() const; + + // internal interface to VoxelMeshGeneratorModeler + + ModelPart& GetModelPart(const std::string& rName) const; + + ModelPart& CreateAndGetModelPart(const std::string& rFullName) const; + + const CartesianMeshColors& GetMeshColors() const; + + std::size_t CalculateCenterOfElementPosition(double Coordinate, int ThisDimension) const; + +}; + +} diff --git a/kratos/modeler/operation/voxel_mesher_operation_factory.cpp b/kratos/modeler/operation/voxel_mesher_operation_factory.cpp new file mode 100644 index 000000000000..f46bc2187285 --- /dev/null +++ b/kratos/modeler/operation/voxel_mesher_operation_factory.cpp @@ -0,0 +1,34 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "voxel_mesher_operation_factory.h" + +#include "includes/kratos_components.h" + +#include "modeler/operation/voxel_mesher_operation.h" +#include "modeler/operation/find_contacts_in_skin_model_part.h" + +namespace Kratos { + +template class KratosComponents; + +void RegisterVoxelMesherOperation() +{ + VoxelMesherOperationFactory::Register("find_contacts_in_skin_model_part"); +} + +} \ No newline at end of file diff --git a/kratos/modeler/operation/voxel_mesher_operation_factory.h b/kratos/modeler/operation/voxel_mesher_operation_factory.h new file mode 100644 index 000000000000..b3049499517a --- /dev/null +++ b/kratos/modeler/operation/voxel_mesher_operation_factory.h @@ -0,0 +1,31 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "modeler/internals/voxel_mesher_component_factory.h" +#include "voxel_mesher_operation.h" + +namespace Kratos { + +using VoxelMesherOperationFactory = VoxelMesherComponentFactory; + +KRATOS_API_EXTERN template class KRATOS_API(KRATOS_CORE) KratosComponents; + +void RegisterVoxelMesherOperation(); + +} \ No newline at end of file diff --git a/kratos/modeler/voxel_mesh_generator_modeler.cpp b/kratos/modeler/voxel_mesh_generator_modeler.cpp new file mode 100644 index 000000000000..437691636fc2 --- /dev/null +++ b/kratos/modeler/voxel_mesh_generator_modeler.cpp @@ -0,0 +1,321 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes + +// External includes + +// Project includes +#include "includes/mesh.h" +#include "includes/element.h" +#include "includes/model_part.h" +#include "geometries/bounding_box.h" +#include "geometries/point.h" +#include "utilities/parallel_utilities.h" +#include "utilities/timer.h" +#include "spatial_containers/geometrical_objects_bins.h" +#include "utilities/model_part_utils.h" + +#include "voxel_mesh_generator_modeler.h" +#include "coloring/voxel_mesher_coloring_factory.h" +#include "key_plane_generation/key_plane_generation_factory.h" +#include "entity_generation/voxel_mesher_entity_generation_factory.h" +#include "operation/voxel_mesher_operation_factory.h" + +namespace Kratos +{ + +/// Default constructor. +VoxelMeshGeneratorModeler::VoxelMeshGeneratorModeler() : Modeler() +{ +} + +/// Constructor. +VoxelMeshGeneratorModeler::VoxelMeshGeneratorModeler( + Model& rModel, Parameters rParameters) + : Modeler(rModel, rParameters ) + , mpModel(&rModel) +{ + rParameters.ValidateAndAssignDefaults(GetDefaultParameters()); + rParameters["key_plane_generator"].ValidateAndAssignDefaults(GetDefaultKeyPlaneGeneratorParameters()); +} + +/// +const Parameters VoxelMeshGeneratorModeler::GetDefaultParameters() const +{ + return Parameters(R"( + { + "key_plane_generator": {}, + "entities_generator_list": [], + "coloring_settings_list": [], + "model_part_operations": [], + "output_filename" : "", + "mdpa_file_name" : "", + "output_model_part_name" : "", + "input_model_part_name" : "", + "default_outside_color" : 1, + "voxel size" : 0.001, + "output_files" : [] + } )"); +} + +/// +const Parameters VoxelMeshGeneratorModeler::GetDefaultKeyPlaneGeneratorParameters() const +{ + return Parameters(R"( + { + "type": "bounding_box", + "Parameters":{} + } )"); +} + +/// +void VoxelMeshGeneratorModeler::SetupModelPart() +{ + ModelPart& main_model_part = ReadModelParts(); + + KRATOS_INFO("Modeler") << "Generating Key planes..." << std::endl; + KeyPlaneGenerationFactory factory; + auto p_key_plane_generator = factory.Create(*this, mParameters["key_plane_generator"]); + p_key_plane_generator->ValidateParameters(); + p_key_plane_generator->Generate(); + + KRATOS_INFO("Modeler") << "Key Planes generated" << std::endl; + + KRATOS_INFO("Modeler") << "Preparing Internal Data Structure" << std::endl; + PreparingTheInternalDataStructure(); + KRATOS_INFO("Modeler") << "Internal Data Structure prepared" << std::endl; + + if(mParameters.Has("coloring_settings_list")){ + ApplyColoring(mParameters["coloring_settings_list"], mParameters["default_outside_color"].GetInt()); + } + if(mParameters.Has("entities_generator_list")){ + GenerateEntities(main_model_part, mParameters["entities_generator_list"]); + } + if(mParameters.Has("model_part_operations")){ + ApplyOperations(mParameters["model_part_operations"]); + } + + for (const auto& single_output_settings : mParameters["output_files"]){ + const std::string type = single_output_settings["type"].GetString(); + if( type == "vtr"){ + mColors.WriteParaViewVTR("Coloring.vtr"); + } + else if (type == "esri_ascii") { + mColors.PrintAllVoxelColorsToAsciiFile(single_output_settings["file_name"].GetString()); + } + } +} + +ModelPart& VoxelMeshGeneratorModeler::ReadModelParts(){ + KRATOS_ERROR_IF_NOT( mParameters.Has("input_model_part_name") ) + << "Missing \"input_model_part_name\" in VoxelMeshGeneratorModeler Parameters." << std::endl; + + mpInputModelPart = &CreateAndGetModelPart(mParameters["input_model_part_name"].GetString()); + + KRATOS_ERROR_IF_NOT(mParameters.Has("mdpa_file_name")) << "mdpa_file_name not defined" << std::endl; + + const std::string data_file_name = mParameters["mdpa_file_name"].GetString(); + + KRATOS_INFO_IF("::[VoxelMeshGeneratorModeler]::", mEchoLevel > 0) << "Importing Cad Model from: " << data_file_name << std::endl; + + // Load the mdpa + if(data_file_name!=""){ + ModelPartIO(data_file_name).ReadModelPart(*mpInputModelPart); + } + + // Create the target model + return CreateAndGetModelPart(mParameters["output_model_part_name"].GetString()); +} + + +void VoxelMeshGeneratorModeler::PreparingTheInternalDataStructure(){ + mColors.SetCoordinates(mKeyPlanes[0], mKeyPlanes[1], mKeyPlanes[2]); + mMeshingData.SetNumberOfDivisions(mKeyPlanes[0].size(), mKeyPlanes[1].size(), mKeyPlanes[2].size()); + + array_1d margins = ZeroVector(3); + for(int i = 0 ; i < 3 ; i++) { + margins[i] = (mKeyPlanes[i].back() - mKeyPlanes[i].front()) * 1.0e-2; + } + + const double margin = *std::max_element(margins.begin(), margins.end()); + mColors.ExtendBoundingBox(mpInputModelPart->Nodes(), margin); +} + +void VoxelMeshGeneratorModeler::ApplyColoring(Parameters ColoringParameters, int OutsideColor){ + Timer::Start("MeshColoring"); + + VoxelMesherColoringFactory factory("coloring strategy"); + mColors.SetAllColors(OutsideColor); + + for(auto parameters : ColoringParameters){ + + if (!parameters.Has("outside_color")) { + parameters.AddInt("outside_color", OutsideColor); + } + + VoxelMesherColoring::Pointer p_coloring = factory.Create(*this, parameters); + + p_coloring->ValidateParameters(); + + std::string model_part_name = parameters["model_part_name"].GetString(); + std::string type = parameters["type"].GetString(); + KRATOS_INFO("Modeler") << "Applying color to " << type << " for " << model_part_name << " model part" << std::endl; + + p_coloring->Apply(); + } + Timer::Stop("MeshColoring"); +} + +void VoxelMeshGeneratorModeler::SetStartIds(ModelPart& rTheVolumeModelPart) +{ + ModelPart& r_root_model_part = rTheVolumeModelPart.GetRootModelPart(); + std::size_t start_node_proposal = r_root_model_part.NodesArray().empty() ? 1 : r_root_model_part.NodesArray().back()->Id() + 1; + mStartNodeId = std::max(start_node_proposal, mStartNodeId); + + std::size_t start_element_proposal = r_root_model_part.ElementsArray().empty() ? 1 : r_root_model_part.ElementsArray().back()->Id() + 1; + mStartElementId = std::max(start_element_proposal, mStartElementId); + + std::size_t start_condition_proposal = r_root_model_part.ConditionsArray().empty()? 1 :r_root_model_part.ConditionsArray().back()->Id() + 1; + mStartConditionId = std::max(start_condition_proposal, mStartConditionId); +} + +void VoxelMeshGeneratorModeler::GenerateEntities( + ModelPart& rTheVolumeModelPart, + Parameters EntityGeneratorParameters + ) +{ + Timer::Start("EntityGeneration"); + VoxelMesherEntityGenerationFactory factory("entity generation strategy"); + + for(auto parameters : EntityGeneratorParameters){ + + auto p_generator = factory.Create(*this, parameters); + p_generator->ValidateParameters(); + + std::string model_part_name = parameters["model_part_name"].GetString(); + std::string type = parameters["type"].GetString(); + KRATOS_INFO("Modeler") << "Generate " << type << " in " << model_part_name << " model part" << std::endl; + + p_generator->Generate(); + } + Timer::Stop("EntityGeneration"); +} + +ModelPart& VoxelMeshGeneratorModeler::CreateAndGetModelPart(std::string const& FullName) +{ + return mpModel->HasModelPart(FullName) ? mpModel->GetModelPart(FullName) : mpModel->CreateModelPart(FullName); +} + + +Node::Pointer VoxelMeshGeneratorModeler::GenerateOrRetrieveNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K + ) +{ + auto& nodal_data = mMeshingData.GetNodalData(I, J, K); + if(nodal_data.IsCreated()){ + rThisNodes.push_back(nodal_data.pGetNode()); + return nodal_data.pGetNode(); + } + + Point global_coordinates = mColors.GetPoint(I,J,K); + Node::Pointer node = this->GenerateNode(rTheVolumeModelPart, global_coordinates); + nodal_data.pSetNode(node); + rThisNodes.push_back(node); + return node; +} + +Node::Pointer VoxelMeshGeneratorModeler::GenerateOrRetrieveQuadraticNode( + ModelPart& rTheVolumeModelPart, + ModelPart::NodesContainerType& rThisNodes, + const std::size_t I, + const std::size_t J, + const std::size_t K + ) +{ + auto& nodal_data = mQuadraticNodeData.GetNodalData(I, J, K); + if(nodal_data.IsCreated()){ + rThisNodes.push_back(nodal_data.pGetNode()); + return nodal_data.pGetNode(); + } + + Point global_coordinates = mColors.GetPoint(I/2.0,J/2.0,K/2.0); + Node::Pointer node = this->GenerateNode(rTheVolumeModelPart, global_coordinates); + nodal_data.pSetNode(node); + rThisNodes.push_back(node); + return node; +} + +Node::Pointer VoxelMeshGeneratorModeler::GenerateNode(ModelPart& rTheVolumeModelPart, const Point& rCoordinates) +{ + Node::Pointer node = Kratos::make_intrusive< Node >( mStartNodeId++, rCoordinates[0], rCoordinates[1], rCoordinates[2]); + // Giving model part's variables list to the node + node->SetSolutionStepVariablesList(rTheVolumeModelPart.pGetNodalSolutionStepVariablesList()); + + //set buffer size + node->SetBufferSize(rTheVolumeModelPart.GetBufferSize()); + + return node; +} + +void VoxelMeshGeneratorModeler::ApplyOperations(Parameters ThisParameters) +{ + VoxelMesherOperationFactory factory("operation"); + int step = 0; + for(auto parameters : ThisParameters){ + auto p_operation = factory.Create(*this, parameters); + p_operation->ValidateParameters(); + + std::stringstream stream; + stream << "Operation " << ++step << " " << parameters["type"].GetString(); + const std::string label = stream.str(); + Timer::Start(label); + + p_operation->Apply(); + + Timer::Stop(label); + } +} + + +Internals::SkinIntersection& VoxelMeshGeneratorModeler::GetIntersections(int Color) +{ + auto iSkinIntersection = mSkinIntersections.find(Color); + if (iSkinIntersection != mSkinIntersections.end()) { + return iSkinIntersection->second; + } + auto emplace_out = mSkinIntersections.emplace( + std::pair(Color, mMeshingData.GetNumberOfDivisions())); + return emplace_out.first->second; +} + + +const Internals::SkinIntersection& VoxelMeshGeneratorModeler::GetIntersections(int Color) const +{ + auto iSkinIntersection = mSkinIntersections.find(Color); + if (iSkinIntersection != mSkinIntersections.end()) { + return iSkinIntersection->second; + } + KRATOS_ERROR << "No intersections defined for color " << Color << std::endl; +} + + +bool VoxelMeshGeneratorModeler::IntersectionsGenerated(int Color) const +{ + return mSkinIntersections.find(Color) != mSkinIntersections.end(); +} + +} // namespace Kratos diff --git a/kratos/modeler/voxel_mesh_generator_modeler.h b/kratos/modeler/voxel_mesh_generator_modeler.h new file mode 100644 index 000000000000..3f7629c84742 --- /dev/null +++ b/kratos/modeler/voxel_mesh_generator_modeler.h @@ -0,0 +1,271 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// +// + +#pragma once + +// System includes + +// External includes + +// Project includes +#include "includes/model_part_io.h" +#include "modeler/modeler.h" +#include "internals/cartesian_mesh_colors.h" +#include "internals/skin_intersection.h" + +namespace Kratos +{ + +///@name Kratos Classes +///@{ + +/// Short class definition. +/** Detail class definition. +*/ +class KRATOS_API(KRATOS_CORE) VoxelMeshGeneratorModeler + : public Modeler +{ +public: + ///@name Type Definitions + ///@{ + + /// Pointer definition of Modeler + KRATOS_CLASS_POINTER_DEFINITION(VoxelMeshGeneratorModeler); + + ///@} + ///@name Life Cycle + ///@{ + + /// Default constructor. + VoxelMeshGeneratorModeler() ; + + /// Constructor. + VoxelMeshGeneratorModeler( + Model& rModel, + Parameters ModelerParameters = Parameters()); + + /// Destructor. + ~VoxelMeshGeneratorModeler() override = default; + + /// Creates the Modeler Pointer + /// Creates the Modeler Pointer + Modeler::Pointer Create( + Model& rModel, const Parameters ModelParameters) const override + { + return Kratos::make_shared(rModel, ModelParameters); + } + + ///@} + ///@name Stages + ///@{ + + void SetupModelPart() override ; + + ModelPart& ReadModelParts(); + + ///@} + ///@name Operators + ///@{ + + ///@} + ///@name Access + ///@{ + + /// Returns the key planes in given direction + const std::vector& GetKeyPlanes(std::size_t Direction) const { + return mKeyPlanes[Direction]; + } + + ///@} + ///@name Input and output + ///@{ + + /// Turn back information as a string. + std::string Info() const override + { + return "VoxelMeshGeneratorModeler"; + } + + /// Print information about this object. + void PrintInfo(std::ostream & rOStream) const override + { + rOStream << Info(); + } + + /// Print object's data. + void PrintData(std::ostream & rOStream) const override + { + } + + const Parameters GetDefaultParameters() const override ; + const Parameters GetDefaultKeyPlaneGeneratorParameters() const; + + ///@} +private: + // Data that I store in the internal data structure for each node of the cartesian grid + class CartesianNodalData + { + Node::Pointer mpNode = nullptr; + + public: + CartesianNodalData() : mpNode(nullptr) {} + Node::Pointer pGetNode() const { return mpNode; } + void pSetNode(Node::Pointer pNode) { mpNode = pNode; } + bool IsCreated() const { return mpNode != nullptr; } + }; + + // A cartesian data storage for the nodes of the cartesian mesh. + // Is used as internal storage + class CartesianData + { + std::vector mNodalData; + array_1d mNumberOfDivisions; + + public: + CartesianData() = default; + + void SetNumberOfDivisions(std::size_t XDivisions, std::size_t YDivisions, std::size_t ZDivisions) + { + mNumberOfDivisions[0] = XDivisions; + mNumberOfDivisions[1] = YDivisions; + mNumberOfDivisions[2] = ZDivisions; + + KRATOS_ERROR_IF((mNumberOfDivisions[0] < 1) || (mNumberOfDivisions[1] < 1) || (mNumberOfDivisions[2] < 1)) + << "The number of division cannot be zero" << std::endl; + + std::size_t size = mNumberOfDivisions[0] * mNumberOfDivisions[1] * mNumberOfDivisions[2]; + mNodalData.assign(size, CartesianNodalData()); + } + + std::size_t GetNodeIndex(std::size_t I, std::size_t J, std::size_t K) const + { + const std::size_t index = I + J * mNumberOfDivisions[0] + K * mNumberOfDivisions[1] * mNumberOfDivisions[0]; + return index; + } + + CartesianNodalData &GetNodalData(std::size_t I, std::size_t J, std::size_t K) + { + const std::size_t index = GetNodeIndex(I,J,K); + return mNodalData[index]; + } + + const array_1d &GetNumberOfDivisions() + { + return mNumberOfDivisions; + } + + bool IsInitialized() const + { + return mNumberOfDivisions[0] && mNumberOfDivisions[1] && mNumberOfDivisions[2]; + } + }; + + struct ContactContainer + { + std::unordered_map> mNodeMap; + std::unordered_map> mConditionsMap; + std::unordered_map mModelPartMap; + std::vector mColorVector; + }; + + ///@name Private members + ///@{ + + std::size_t mStartNodeId = 0; + std::size_t mStartElementId = 0; + std::size_t mStartConditionId = 0; + + Model* mpModel = nullptr; + ModelPart* mpInputModelPart = nullptr; + array_1d,3> mKeyPlanes; + std::map mModelPartsColors; + Internals::CartesianMeshColors mColors; + CartesianData mMeshingData; + CartesianData mQuadraticNodeData{}; + std::map mSkinIntersections; + + ///@} + ///@name Private Operations + ///@{ + + /// This initializes de internal cartesian mesh data structure to be used for coloring + void PreparingTheInternalDataStructure(); + + /// Goes over the coloring array and apply them to the internal data structure + void ApplyColoring(Parameters ColoringParameters, int OutsideColor); + + void SetStartIds(ModelPart& rTheVolumeModelPart); + + ModelPart& CreateAndGetModelPart(std::string const& FullName); + + void GenerateEntities(ModelPart& rTheVolumeModelPart, Parameters EntityGeneratorParameters); + + Node::Pointer GenerateOrRetrieveNode(ModelPart& rTheVolumeModelPart, ModelPart::NodesContainerType& rThisNodes, const std::size_t I, const std::size_t J, const std::size_t K); + + Node::Pointer GenerateOrRetrieveQuadraticNode(ModelPart& rTheVolumeModelPart, ModelPart::NodesContainerType& rThisNodes, const std::size_t I, const std::size_t J, const std::size_t K); + + Node::Pointer GenerateNode(ModelPart& rTheVolumeModelPart, const Point& rCoordinates); + + void ApplyOperations(Parameters ThisParameters); + + void GenerateIntersectedSkinElements( + ModelPart& rIntersectionModelPart, + double Color, + std::size_t PropertiesId, + const Internals::SkinIntersection& rSkinIntersection); + + Internals::SkinIntersection& GetIntersections(int Color); + + const Internals::SkinIntersection& GetIntersections(int Color) const; + + bool IntersectionsGenerated(int Color) const; + + ///@} + ///@name Friends + ///@{ + + friend class VoxelMesherColoring; + + friend class VoxelMesherKeyPlaneGeneration; + + friend class VoxelMesherEntityGeneration; + + friend class VoxelMesherOperation; + + ///@} +}; // Class VoxelMeshGeneratorModeler + +///@} +///@name Input and output +///@{ + +/// input stream function +inline std::istream& operator >> ( + std::istream& rIStream, + VoxelMeshGeneratorModeler& rThis); + +/// output stream function +inline std::ostream& operator << ( + std::ostream& rOStream, + const VoxelMeshGeneratorModeler& rThis) +{ + rThis.PrintInfo(rOStream); + rOStream << std::endl; + rThis.PrintData(rOStream); + + return rOStream; +} + +///@} + +} // namespace Kratos. diff --git a/kratos/python/add_modeler_to_python.cpp b/kratos/python/add_modeler_to_python.cpp index 6133ad8cf659..e1ed91b5d1c6 100644 --- a/kratos/python/add_modeler_to_python.cpp +++ b/kratos/python/add_modeler_to_python.cpp @@ -26,6 +26,7 @@ #include "modeler/duplicate_mesh_modeler.h" #include "modeler/copy_properties_modeler.h" #include "modeler/combine_model_part_modeler.h" +#include "modeler/voxel_mesh_generator_modeler.h" namespace Kratos::Python { @@ -111,6 +112,10 @@ void AddModelerToPython(pybind11::module& m) py::class_< CreateEntitiesFromGeometriesModeler, CreateEntitiesFromGeometriesModeler::Pointer, Modeler >(m, "CreateEntitiesFromGeometriesModeler") .def(py::init()) ; + + py::class_(m, "VoxelMeshGeneratorModeler") + .def(py::init()) + ; } } // namespace Kratos::Python. \ No newline at end of file diff --git a/kratos/python/add_strategies_to_python.cpp b/kratos/python/add_strategies_to_python.cpp index 8b1f2035b47b..410c760f9f02 100644 --- a/kratos/python/add_strategies_to_python.cpp +++ b/kratos/python/add_strategies_to_python.cpp @@ -661,6 +661,8 @@ namespace Kratos:: Python .def("GetUseOldStiffnessInFirstIterationFlag", &ResidualBasedNewtonRaphsonStrategyType::GetUseOldStiffnessInFirstIterationFlag) .def("SetReformDofSetAtEachStepFlag", &ResidualBasedNewtonRaphsonStrategyType::SetReformDofSetAtEachStepFlag) .def("GetReformDofSetAtEachStepFlag", &ResidualBasedNewtonRaphsonStrategyType::GetReformDofSetAtEachStepFlag) + .def("GetNonconvergedSolutions", &ResidualBasedNewtonRaphsonStrategyType::GetNonconvergedSolutions) + .def("SetUpNonconvergedSolutionsFlag", &ResidualBasedNewtonRaphsonStrategyType::SetUpNonconvergedSolutionsFlag) ; // ARC-LENGTH diff --git a/kratos/solving_strategies/strategies/residualbased_newton_raphson_strategy.h b/kratos/solving_strategies/strategies/residualbased_newton_raphson_strategy.h index 59ca94f739c7..69f747077aff 100644 --- a/kratos/solving_strategies/strategies/residualbased_newton_raphson_strategy.h +++ b/kratos/solving_strategies/strategies/residualbased_newton_raphson_strategy.h @@ -879,6 +879,41 @@ class ResidualBasedNewtonRaphsonStrategy KRATOS_CATCH(""); } + /** + * @brief Gets the current solution vector + * @param rDofSet The set of degrees of freedom (DOFs) + * @param this_solution The vector that will be filled with the current solution values + * @details This method retrieves the current solution values for the provided DOF set. + * The provided solution vector will be resized to match the size of the DOF set if necessary, + * and will be filled with the solution values corresponding to each DOF. Each value is accessed + * using the equation ID associated with each DOF. + */ + void GetCurrentSolution(DofsArrayType& rDofSet, Vector& this_solution) { + this_solution.resize(rDofSet.size()); + block_for_each(rDofSet, [&](const auto& r_dof) { + this_solution[r_dof.EquationId()] = r_dof.GetSolutionStepValue(); + }); + } + + /** + * @brief Gets the matrix of non-converged solutions and the DOF set + * @return A tuple containing the matrix of non-converged solutions and the DOF set + * @details This method returns a tuple where the first element is a matrix of non-converged solutions and the second element is the corresponding DOF set. + */ + std::tuple GetNonconvergedSolutions(){ + return std::make_tuple(mNonconvergedSolutionsMatrix, GetBuilderAndSolver()->GetDofSet()); + } + + /** + * @brief Sets the state for storing non-converged solutions. + * @param state The state to set for storing non-converged solutions (true to enable, false to disable). + * @details This method enables or disables the storage of non-converged solutions at each iteration + * by setting the appropriate flag. When the flag is set to true, non-converged solutions will be stored. + */ + void SetUpNonconvergedSolutionsFlag(bool state) { + mStoreNonconvergedSolutionsFlag = state; + } + /** * @brief Solves the current step. This function returns true if a solution has been found, false otherwise. */ @@ -889,6 +924,13 @@ class ResidualBasedNewtonRaphsonStrategy typename TSchemeType::Pointer p_scheme = GetScheme(); typename TBuilderAndSolverType::Pointer p_builder_and_solver = GetBuilderAndSolver(); auto& r_dof_set = p_builder_and_solver->GetDofSet(); + std::vector NonconvergedSolutions; + + if (mStoreNonconvergedSolutionsFlag) { + Vector initial; + GetCurrentSolution(r_dof_set,initial); + NonconvergedSolutions.push_back(initial); + } TSystemMatrixType& rA = *mpA; TSystemVectorType& rDx = *mpDx; @@ -929,6 +971,12 @@ class ResidualBasedNewtonRaphsonStrategy p_scheme->FinalizeNonLinIteration(r_model_part, rA, rDx, rb); mpConvergenceCriteria->FinalizeNonLinearIteration(r_model_part, r_dof_set, rA, rDx, rb); + if (mStoreNonconvergedSolutionsFlag) { + Vector first; + GetCurrentSolution(r_dof_set,first); + NonconvergedSolutions.push_back(first); + } + if (is_converged) { if (mpConvergenceCriteria->GetActualizeRHSflag()) { TSparseSpace::SetToZero(rb); @@ -996,6 +1044,12 @@ class ResidualBasedNewtonRaphsonStrategy p_scheme->FinalizeNonLinIteration(r_model_part, rA, rDx, rb); mpConvergenceCriteria->FinalizeNonLinearIteration(r_model_part, r_dof_set, rA, rDx, rb); + if (mStoreNonconvergedSolutionsFlag == true){ + Vector ith; + GetCurrentSolution(r_dof_set,ith); + NonconvergedSolutions.push_back(ith); + } + residual_is_updated = false; if (is_converged == true) @@ -1039,6 +1093,15 @@ class ResidualBasedNewtonRaphsonStrategy if (mCalculateReactionsFlag == true) p_builder_and_solver->CalculateReactions(p_scheme, r_model_part, rA, rDx, rb); + if (mStoreNonconvergedSolutionsFlag) { + mNonconvergedSolutionsMatrix = Matrix( r_dof_set.size(), NonconvergedSolutions.size() ); + for (std::size_t i = 0; i < NonconvergedSolutions.size(); ++i) { + block_for_each(r_dof_set, [&](const auto& r_dof) { + mNonconvergedSolutionsMatrix(r_dof.EquationId(), i) = NonconvergedSolutions[i](r_dof.EquationId()); + }); + } + } + return is_converged; } @@ -1265,6 +1328,20 @@ class ResidualBasedNewtonRaphsonStrategy bool mKeepSystemConstantDuringIterations; // Flag to allow keeping system matrix constant during iterations + /** + * @brief This matrix stores the non-converged solutions + * @details The matrix is structured such that each column represents the solution vector at a specific non-converged iteration. + */ + Matrix mNonconvergedSolutionsMatrix; + + /** + * @brief Flag indicating whether to store non-converged solutions + * @details Only when set to true (by calling the SetUpNonconvergedSolutionsGathering method) will the non-converged solutions at each iteration be stored. + */ + bool mStoreNonconvergedSolutionsFlag = false; + + + ///@} ///@name Private Operators ///@{ diff --git a/kratos/sources/kratos_application.cpp b/kratos/sources/kratos_application.cpp index 3797b4000999..a13e3147b481 100644 --- a/kratos/sources/kratos_application.cpp +++ b/kratos/sources/kratos_application.cpp @@ -31,6 +31,11 @@ #include "factories/standard_linear_solver_factory.h" #include "factories/standard_preconditioner_factory.h" +#include "modeler/coloring/voxel_mesher_coloring_factory.h" +#include "modeler/key_plane_generation/key_plane_generation_factory.h" +#include "modeler/entity_generation/voxel_mesher_entity_generation_factory.h" +#include "modeler/operation/voxel_mesher_operation_factory.h" + namespace Kratos { KratosApplication::KratosApplication(const std::string& ApplicationName) @@ -216,6 +221,7 @@ void KratosApplication::RegisterKratosCore() { KRATOS_REGISTER_MODELER("SerialModelPartCombinatorModeler", mSerialModelPartCombinatorModeler); KRATOS_REGISTER_MODELER("CombineModelPartModeler", mCombineModelPartModeler); KRATOS_REGISTER_MODELER("ConnectivityPreserveModeler", mConnectivityPreserveModeler); + KRATOS_REGISTER_MODELER("VoxelMeshGeneratorModeler", mVoxelMeshGeneratorModeler); // Register general geometries: // Point register: @@ -294,5 +300,11 @@ void KratosApplication::RegisterKratosCore() { // Register ConstitutiveLaw BaseClass KRATOS_REGISTER_CONSTITUTIVE_LAW("ConstitutiveLaw", mConstitutiveLaw); + + //Register Voxel Modeler modular components + RegisterVoxelMesherColoring(); + RegisterVoxelMesherKeyPlaneGeneration(); + RegisterVoxelMesherEntityGeneration(); + RegisterVoxelMesherOperation(); } } // namespace Kratos. diff --git a/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh.mdpa b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh.mdpa new file mode 100644 index 000000000000..994d159ae195 --- /dev/null +++ b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh.mdpa @@ -0,0 +1,56 @@ +Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 0.03 0.03 0.09 + 2 0.03 -0.03 0.09 + 3 0.03 -0.03 0.03 + 4 0.03 0.03 0.03 + 5 -0.03 0.03 0.09 + 6 -0.03 0.03 0.03 + 7 -0.03 -0.03 0.09 + 8 -0.03 -0.03 0.03 +End Nodes +Begin Elements Element3D3N + 1 1 1 2 3 + 2 1 3 4 1 + 3 1 5 1 4 + 4 1 4 6 5 + 5 1 7 5 6 + 6 1 6 8 7 + 7 1 7 8 3 + 8 1 3 2 7 + 9 1 7 2 1 + 10 1 1 5 7 + 11 1 8 6 4 + 12 1 4 3 8 +End Elements +Begin SubModelPart workpiece +Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 +End SubModelPartNodes +Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 +End SubModelPartElements +End SubModelPart \ No newline at end of file diff --git a/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh_conditions.mdpa b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh_conditions.mdpa new file mode 100644 index 000000000000..39932fe27dfd --- /dev/null +++ b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh_conditions.mdpa @@ -0,0 +1,56 @@ +Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 0.03 0.03 0.09 + 2 0.03 -0.03 0.09 + 3 0.03 -0.03 0.03 + 4 0.03 0.03 0.03 + 5 -0.03 0.03 0.09 + 6 -0.03 0.03 0.03 + 7 -0.03 -0.03 0.09 + 8 -0.03 -0.03 0.03 +End Nodes +Begin Conditions SurfaceCondition3D3N + 1 1 1 2 3 + 2 1 3 4 1 + 3 1 5 1 4 + 4 1 4 6 5 + 5 1 7 5 6 + 6 1 6 8 7 + 7 1 7 8 3 + 8 1 3 2 7 + 9 1 7 2 1 + 10 1 1 5 7 + 11 1 8 6 4 + 12 1 4 3 8 +End Conditions +Begin SubModelPart workpiece +Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 +End SubModelPartNodes +Begin SubModelPartConditions + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 +End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/two_particles.mdpa b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/two_particles.mdpa new file mode 100644 index 000000000000..88e7b15bdbe6 --- /dev/null +++ b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/two_particles.mdpa @@ -0,0 +1,14 @@ +Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 -0.02 -0.02 0.04 + 2 0.03 0.03 0.09 +End Nodes +Begin NodalData RADIUS +1 0 0.04 +2 0 0.06 +End NodalData \ No newline at end of file diff --git a/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/un_connected_parts.mdpa b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/un_connected_parts.mdpa new file mode 100644 index 000000000000..73f5930d6be4 --- /dev/null +++ b/kratos/tests/auxiliar_files_for_python_unittest/voxel_mesh_modeler/un_connected_parts.mdpa @@ -0,0 +1,51 @@ +Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 0.01 0.01 0.01 + 2 0.01 0.02 0.01 + 3 0.01 0.01 0.05 + 4 0.07 0.07 0.01 + 5 0.08 0.07 0.01 + 6 0.07 0.07 0.05 + 7 0.05 0.05 0.08 + 8 0.05 0.08 0.08 + 9 0.04 0.08 0.08 +End Nodes +Begin Conditions SurfaceCondition3D3N + 1 1 1 2 3 + 2 1 4 5 6 + 3 1 7 8 9 + 4 1 1 2 4 +End Conditions +Begin SubModelPart workpiece +Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 +End SubModelPartNodes +Begin SubModelPartConditions + 1 + 2 + 3 +End SubModelPartConditions +End SubModelPart +Begin SubModelPart base +Begin SubModelPartNodes + 1 + 2 + 4 +End SubModelPartNodes +Begin SubModelPartConditions + 4 +End SubModelPartConditions +End SubModelPart \ No newline at end of file diff --git a/kratos/tests/cpp_tests/modeler/test_key_plane_generation_with_refinement.cpp b/kratos/tests/cpp_tests/modeler/test_key_plane_generation_with_refinement.cpp new file mode 100644 index 000000000000..62ec66ef04eb --- /dev/null +++ b/kratos/tests/cpp_tests/modeler/test_key_plane_generation_with_refinement.cpp @@ -0,0 +1,178 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes +#include + +// External includes + +// Project includes +#include "testing/testing.h" +#include "includes/kratos_application.h" +#include "includes/kernel.h" + +#include "modeler/voxel_mesh_generator_modeler.h" +#include "modeler/key_plane_generation/key_plane_generation_factory.h" + +namespace Kratos::Testing { + +namespace { +void WriteCubeSkinMeshMdpaFile() +{ + Kratos::shared_ptr p_input(new std::stringstream( + R"input( + Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 0.03 0.03 0.09 + 2 0.03 -0.03 0.09 + 3 0.03 -0.03 0.03 + 4 0.03 0.03 0.03 + 5 -0.03 0.03 0.09 + 6 -0.03 0.03 0.03 + 7 -0.03 -0.03 0.09 + 8 -0.03 -0.03 0.03 + + 9 -0.03 -0.02 0.05 + 10 -0.01 -0.02 0.07 + 11 -0.01 -0.01 0.05 +End Nodes +Begin Elements Element3D3N + 1 1 1 2 3 + 2 1 3 4 1 + 3 1 5 1 4 + 4 1 4 6 5 + 5 1 7 5 6 + 6 1 6 8 7 + 7 1 7 8 3 + 8 1 3 2 7 + 9 1 7 2 1 + 10 1 1 5 7 + 11 1 8 6 4 + 12 1 4 3 8 + 13 1 9 10 11 +End Elements +Begin SubModelPart workpiece +Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 +End SubModelPartNodes +Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 +End SubModelPartElements +End SubModelPart +Begin SubModelPart refinement1 +Begin SubModelPartNodes +9 +10 +11 +End SubModelPartNodes +Begin SubModelPartElements +13 +End SubModelPartElements +End SubModelPart + )input")); + Model current_model; + ModelPartIO model_part_io(p_input); + + ModelPart& model_part_0 = + current_model.CreateModelPart("tmp_main_model_part"); + model_part_io.ReadModelPart(model_part_0); + + // Create the output .mdpa file + std::string output_file_name = "cube_skin_mesh"; + std::fstream output_file; + output_file.open(output_file_name + ".mdpa", std::fstream::out); + output_file.close(); + + // Fill the output .mdpa file + ModelPartIO model_part_io_write(output_file_name, IO::WRITE); + model_part_io_write.WriteModelPart(model_part_0); +} +} // namespace + +KRATOS_TEST_CASE_IN_SUITE(VoxelMeshGeneratorModelerWithRefinement, KratosCoreFastSuite) +{ + using namespace Kratos; + + WriteCubeSkinMeshMdpaFile(); + + Parameters mesher_parameters(R"( + { + "output_model_part_name" : "output_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "cube_skin_mesh", + "key_plane_generator": { + "type" : "outer_shell_with_refinement", + "Parameters" : { + "voxel_sizes" : [0.005, 0.005, 0.005], + "refinement_zones":[ + { + "refined_modelpart" : "skin_model_part.refinement1", + "refined_zone" : {}, + "voxel_sizes_ratio": [0.5, 0.5, 0.5] + }] + + } + } + })"); + + Model current_model; + current_model.CreateModelPart("main_model_part"); + + // Generate the skin + current_model.CreateModelPart("skin_model_part"); + + // Generating the mesh + auto voxel_mesher = VoxelMeshGeneratorModeler(current_model, mesher_parameters); + voxel_mesher.SetupGeometryModel(); + voxel_mesher.ReadModelParts(); + + KeyPlaneGenerationFactory factory; + auto p_key_plane_generator = factory.Create(voxel_mesher, mesher_parameters["key_plane_generator"]); + p_key_plane_generator->ValidateParameters(); + p_key_plane_generator->Generate(); + + std::vector x_key_planes {-0.0325,-0.03,-0.0275,-0.025,-0.0225,-0.02,-0.0175,-0.015,-0.0125,-0.01,-0.0075,-0.005,-0.0025,0,0.0025,0.005,0.0075,0.01,0.0125,0.015,0.0175,0.02,0.0225,0.025,0.0275,0.03,0.0325}; + std::vector y_key_planes {-0.035,-0.03,-0.025,-0.02,-0.0175,-0.015,-0.0125,-0.01,-0.0075,-0.005,-0.0025,0,0.0025,0.005,0.0075,0.01,0.0125,0.015,0.0175,0.02,0.0225,0.025,0.0275,0.03,0.0325}; + std::vector z_key_planes {0.025,0.03,0.034,0.038,0.042,0.046,0.05,0.0525,0.055,0.0575,0.06,0.0625,0.065,0.0675,0.07,0.0725,0.075,0.0775,0.08,0.0825,0.085,0.0875,0.09,0.0925}; + + // delete work file + std::remove("cube_skin_mesh.mdpa"); + + KRATOS_EXPECT_VECTOR_NEAR(x_key_planes, voxel_mesher.GetKeyPlanes(0), 1e-6); + KRATOS_EXPECT_VECTOR_NEAR(y_key_planes, voxel_mesher.GetKeyPlanes(1), 1e-6); + KRATOS_EXPECT_VECTOR_NEAR(z_key_planes, voxel_mesher.GetKeyPlanes(2), 1e-6); +} + +} // namespace Kratos::Testing diff --git a/kratos/tests/cpp_tests/modeler/test_voxel_mesh_modeler.cpp b/kratos/tests/cpp_tests/modeler/test_voxel_mesh_modeler.cpp new file mode 100644 index 000000000000..a7f09c9c6b0f --- /dev/null +++ b/kratos/tests/cpp_tests/modeler/test_voxel_mesh_modeler.cpp @@ -0,0 +1,667 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// Kratos default license: kratos/license.txt +// +// Main authors: Pooyan Dadvand +// + +// System includes +#include + +// External includes + +// Project includes +#include "testing/testing.h" +#include "geometries/tetrahedra_3d_4.h" +#include "geometries/hexahedra_3d_8.h" +#include "includes/kratos_application.h" +#include "includes/kernel.h" + +#include "modeler/voxel_mesh_generator_modeler.h" + +namespace Kratos::Testing { + +namespace { +void WriteCubeSkinMeshMdpaFileForVoxelModelerTest() +{ + Kratos::shared_ptr p_input(new std::stringstream( + R"input( + Begin ModelPartData +End ModelPartData +Begin Properties 0 +End Properties +Begin Properties 1 +End Properties +Begin Nodes + 1 0.03 0.03 0.09 + 2 0.03 -0.03 0.09 + 3 0.03 -0.03 0.03 + 4 0.03 0.03 0.03 + 5 -0.03 0.03 0.09 + 6 -0.03 0.03 0.03 + 7 -0.03 -0.03 0.09 + 8 -0.03 -0.03 0.03 +End Nodes +Begin Elements Element3D3N + 1 1 1 2 3 + 2 1 3 4 1 + 3 1 5 1 4 + 4 1 4 6 5 + 5 1 7 5 6 + 6 1 6 8 7 + 7 1 7 8 3 + 8 1 3 2 7 + 9 1 7 2 1 + 10 1 1 5 7 + 11 1 8 6 4 + 12 1 4 3 8 +End Elements +Begin SubModelPart workpiece +Begin SubModelPartNodes + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 +End SubModelPartNodes +Begin SubModelPartElements + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 +End SubModelPartElements +End SubModelPart + )input")); + + Model current_model; + + ModelPartIO model_part_io(p_input); + + ModelPart& model_part_0 = + current_model.CreateModelPart("tmp_main_model_part"); + model_part_io.ReadModelPart(model_part_0); + + // Create the output .mdpa file + std::string output_file_name = "cube_skin_mesh"; + std::fstream output_file; + output_file.open(output_file_name + ".mdpa", std::fstream::out); + output_file.close(); + + // Fill the output .mdpa file + ModelPartIO* model_part_io_write = new ModelPartIO(output_file_name, IO::WRITE); + model_part_io_write->WriteModelPart(model_part_0); +} +} // namespace + +KRATOS_TEST_CASE_IN_SUITE(VoxelMeshGeneratorModelerKeyPlaneBySize, + AdditiveManufacturingApplicationFastSuite) +{ + using namespace Kratos; + + WriteCubeSkinMeshMdpaFileForVoxelModelerTest(); + + Parameters mesher_parameters(R"( + { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.01, 0.025, 0.03], + "min_point" : [0.01, 0.02, 0.03], + "max_point" : [0.06, 0.08, 0.08] + } + } + })"); + + Model current_model; + current_model.CreateModelPart("main_model_part"); + + // Generate the skin + current_model.CreateModelPart("skin_model_part"); + + // Generating the mesh + auto voxel_mesher = VoxelMeshGeneratorModeler(current_model, mesher_parameters); + voxel_mesher.SetupGeometryModel(); + voxel_mesher.SetupModelPart(); + + std::vector x_key_planes{0.01, 0.02, 0.03, 0.04, 0.05, 0.06}; + std::vector y_key_planes{0.02, 0.05, 0.08}; + std::vector z_key_planes{0.03, 0.055, 0.08}; + + KRATOS_EXPECT_VECTOR_NEAR(x_key_planes, voxel_mesher.GetKeyPlanes(0), 1e-6); + KRATOS_EXPECT_VECTOR_NEAR(y_key_planes, voxel_mesher.GetKeyPlanes(1), 1e-6); + KRATOS_EXPECT_VECTOR_NEAR(z_key_planes, voxel_mesher.GetKeyPlanes(2), 1e-6); + +} + +KRATOS_TEST_CASE_IN_SUITE(XCartesianRayPlaneIntersection, KratosCoreFastSuite) + { + Point::Pointer p_point_1=Kratos::make_shared(.4, 0.00, 0.00); + Point::Pointer p_point_2=Kratos::make_shared(.4, 1.00, 0.00); + Point::Pointer p_point_3=Kratos::make_shared(.4, 1.00, 1.00); + Point::Pointer p_point_4=Kratos::make_shared(.4, 0.00, 1.00); + + Triangle3D3 triangle_1(p_point_1, p_point_2, p_point_3); + Triangle3D3 triangle_2(p_point_1, p_point_3, p_point_4); + + Kratos::Internals::CartesianRay> ray_1(0, Point(0.00, 0.50, 0.50), Point(1.00, 0.50, 0.50)); + Kratos::Internals::CartesianRay> ray_2(0, Point(0.00, 0.00, 0.00), Point(1.00, 0.00, 0.00)); + Kratos::Internals::CartesianRay> ray_3(0, Point(0.00, 0.20, 0.70), Point(1.00, 0.20, 0.70)); + + ray_1.AddIntersection(triangle_1, 1e-9); + ray_2.AddIntersection(triangle_1, 1e-9); + ray_3.AddIntersection(triangle_1, 1e-9); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_3.GetIntersections().size(), 0); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[0].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[0].first, .4, 1e-6); + + ray_1.AddIntersection(triangle_2, 1e-9); + ray_2.AddIntersection(triangle_2, 1e-9); + ray_3.AddIntersection(triangle_2, 1e-9); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 2); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 2); + KRATOS_EXPECT_EQ(ray_3.GetIntersections().size(), 1); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[1].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[1].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_3.GetIntersections()[0].first, .4, 1e-6); + + ray_1.CollapseIntersectionPoints(1e-6); + ray_2.CollapseIntersectionPoints(1e-6); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 0); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[0].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[0].first, .4, 1e-6); + } + + + KRATOS_TEST_CASE_IN_SUITE(XCartesianRayLongPlaneIntersection, KratosCoreFastSuite) + { + Point::Pointer p_point_1=Kratos::make_shared(.4, 0.00, 0.00); + Point::Pointer p_point_2=Kratos::make_shared(.4, 1.00, 0.00); + Point::Pointer p_point_3=Kratos::make_shared(.4, 1.00, 1000.00); + Point::Pointer p_point_4=Kratos::make_shared(.4, 0.00, 1000.00); + + Triangle3D3 triangle_1(p_point_1, p_point_2, p_point_3); + Triangle3D3 triangle_2(p_point_1, p_point_3, p_point_4); + + Kratos::Internals::CartesianRay> ray_1(0, Point(0.00, 0.50, 500.0), Point(1.00, 0.50, 500.0)); + Kratos::Internals::CartesianRay> ray_2(0, Point(0.00, 0.00, 0.00), Point(1.00, 0.00, 0.00)); + Kratos::Internals::CartesianRay> ray_3(0, Point(0.00, 0.20, 700.0), Point(1.00, 0.20, 700.0)); + + ray_1.AddIntersection(triangle_1, 1e-9); + ray_2.AddIntersection(triangle_1, 1e-9); + ray_3.AddIntersection(triangle_1, 1e-9); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_3.GetIntersections().size(), 0); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[0].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[0].first, .4, 1e-6); + + ray_1.AddIntersection(triangle_2, 1e-9); + ray_2.AddIntersection(triangle_2, 1e-9); + ray_3.AddIntersection(triangle_2, 1e-9); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 2); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 2); + KRATOS_EXPECT_EQ(ray_3.GetIntersections().size(), 1); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[1].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[1].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_3.GetIntersections()[0].first, .4, 1e-6); + + ray_1.CollapseIntersectionPoints(1e-6); + ray_2.CollapseIntersectionPoints(1e-6); + + KRATOS_EXPECT_EQ(ray_1.GetIntersections().size(), 1); + KRATOS_EXPECT_EQ(ray_2.GetIntersections().size(), 0); + + KRATOS_EXPECT_NEAR(ray_1.GetIntersections()[0].first, .4, 1e-6); + KRATOS_EXPECT_NEAR(ray_2.GetIntersections()[0].first, .4, 1e-6); + } + + + KRATOS_TEST_CASE_IN_SUITE(XCartesianRayPlaneMarkIntersectedIntervals, KratosCoreFastSuite) + { + Point::Pointer p_point_1=Kratos::make_shared(.4, 0.00, 0.00); + Point::Pointer p_point_2=Kratos::make_shared(.4, 1.00, 0.00); + Point::Pointer p_point_3=Kratos::make_shared(.4, 1.00, 1.00); + Point::Pointer p_point_4=Kratos::make_shared(.4, 0.00, 1.00); + + Triangle3D3 triangle_1(p_point_1, p_point_2, p_point_3); + Triangle3D3 triangle_2(p_point_1, p_point_3, p_point_4); + + Kratos::Internals::CartesianRay> ray_1(0, Point(0.00, 0.50, 0.50), Point(1.00, 0.50, 0.50)); + + ray_1.AddIntersection(triangle_1, 1e-9); + ray_1.AddIntersection(triangle_2, 1e-9); + + ray_1.CollapseIntersectionPoints(1e-6); + + std::vector colors; + std::vector coordinates_1{0.05, 0.15, 0.25, 0.30, 0.45, 0.50, 0.60, 0.70, 0.80, 0.90}; + ray_1.MarkIntersectedIntervals(coordinates_1, -1, 1, colors, 1e-6); + + for(std::size_t i = 0 ; i < colors.size() ; i++){ + if(i == 3){ + KRATOS_EXPECT_NEAR(colors[i], -1, 1e-6); + } + else { + KRATOS_EXPECT_NEAR(colors[i], 1, 1e-6); + } + } + + std::vector coordinates_2{0.00, 0.10, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90}; + ray_1.MarkIntersectedIntervals(coordinates_2, -1, 1, colors, 1e-6); + + for(std::size_t i = 0 ; i < colors.size() ; i++){ + if(i == 3){ + KRATOS_EXPECT_NEAR(colors[i], -1, 1e-6); + } + else { + KRATOS_EXPECT_NEAR(colors[i], 1, 1e-6); + } + } + + } + + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsSetCoordinates, KratosCoreFastSuite) + { + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(6); + } + + Point min_point(1.00, 2.00, 3.00); + for(std::size_t i = 0 ; i < coordinates.size() ; i++){ + const double min_coordinate_i = min_point[i]; + for(std::size_t j = 0 ; j < coordinates[i].size() ; j++) + coordinates[i][j] = j * 2.0 + min_coordinate_i; + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + + for (std::size_t k = 0; k <= 5; k++) { + for (std::size_t j = 0; j <= 5; j++) { + for (std::size_t i = 0; i <= 5; i++) { + double x = 2.00*i + 1.00; + double y = 2.00*j + 2.00; + double z = 2.00*k + 3.00; + Point point = mesh_colors.GetPoint(i,j,k); + KRATOS_EXPECT_NEAR(point.X(), x, 1e-6); + KRATOS_EXPECT_NEAR(point.Y(), y, 1e-6); + KRATOS_EXPECT_NEAR(point.Z(), z, 1e-6); + } + } + } + } + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsInitialRays, KratosCoreFastSuite) + { + std::size_t size = 4; + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(size); + } + + Point min_point(1.00, 2.00, 3.00); + for(std::size_t i = 0 ; i < 3 ; i++){ + const double min_coordinate_i = min_point[i]; + for(std::size_t j = 0 ; j < size ; j++) + coordinates[i][j] = j * 2.0 + min_coordinate_i; + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + + array_1d min_position; + array_1d max_position; + + for(std::size_t i = 0 ; i < 3 ; i++){ + min_position[i] = 0; + max_position[i] = size; + } + + mesh_colors.InitializeRays(min_position, max_position, "nodes"); + + for (std::size_t i = 0; i < size; i++) { + for (std::size_t j = 0; j < size; j++) { + double x = 2.00*i + 1.00; + double y = 2.00*j + 2.00; + double z = 2.00*(size - 1.00) + 3.00; + auto& ray = mesh_colors.GetXYRay(i,j); + Point& point = ray.GetPoint1(); + KRATOS_EXPECT_NEAR(point.X(), x, 1e-6); + KRATOS_EXPECT_NEAR(point.Y(), y, 1e-6); + KRATOS_EXPECT_NEAR(point.Z(), min_point.Z(), 1e-6); + + point = ray.GetPoint2(); + KRATOS_EXPECT_NEAR(point.X(), x, 1e-6); + KRATOS_EXPECT_NEAR(point.Y(), y, 1e-6); + KRATOS_EXPECT_NEAR(point.Z(), z, 1e-6); + } + } + } + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsAddGeometry, KratosCoreFastSuite) + { + + Model current_model; + + // Generate the skin + ModelPart &skin_model_part = current_model.CreateModelPart("Skin"); + + std::size_t size = 5; + double cube_size = static_cast(size - 1); + + skin_model_part.AddNodalSolutionStepVariable(VELOCITY); + skin_model_part.CreateNewNode(901, 0.0, 0.0, 0.0); + skin_model_part.CreateNewNode(902, cube_size, 0.0, 0.0); + skin_model_part.CreateNewNode(903, cube_size, cube_size, 0.0); + skin_model_part.CreateNewNode(904, 0.0, 0.0, cube_size); + Properties::Pointer p_properties(new Properties(0)); + skin_model_part.CreateNewElement("Element3D3N", 901, { 901,902,903 }, p_properties); + skin_model_part.CreateNewElement("Element3D3N", 902, { 901,904,903 }, p_properties); + skin_model_part.CreateNewElement("Element3D3N", 903, { 902,903,904 }, p_properties); + skin_model_part.CreateNewElement("Element3D3N", 904, { 901,902,904 }, p_properties); + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(size); + } + + for(std::size_t i = 0 ; i < 3 ; i++){ + for(std::size_t j = 0 ; j < size ; j++) + coordinates[i][j] = static_cast(j); + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + + mesh_colors.ExtendBoundingBox(skin_model_part.Nodes(), 1.0e-6); + + array_1d min_position; + array_1d max_position; + + for(std::size_t i = 0 ; i < 3 ; i++){ + min_position[i] = 0; + max_position[i] = size; + } + + mesh_colors.InitializeRays(min_position, max_position, "nodes"); + + for(auto& element : skin_model_part.Elements()) + { + Element::GeometryType& r_geometry = element.GetGeometry(); + mesh_colors.AddGeometry(r_geometry, true); + } + + for (std::size_t i = 0; i < size; i++) { + for (std::size_t j = 0; j < size; j++) { + auto& ray = mesh_colors.GetXYRay(i,j); + if(i>=j){ + KRATOS_EXPECT_EQ(ray.GetIntersections().size(), 2); + } + else { + KRATOS_EXPECT_EQ(ray.GetIntersections().size(), 0); + } + } + } + } + + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsXPlaneFaceColoring, KratosCoreFastSuite) + { + + Model current_model; + + // Generate the skin + ModelPart &skin_model_part = current_model.CreateModelPart("Skin"); + + skin_model_part.CreateNewNode(1, .4, 0.00, 0.00); + skin_model_part.CreateNewNode(2, .4, 1.00, 0.00); + skin_model_part.CreateNewNode(3, .4, 1.00, 1.00); + skin_model_part.CreateNewNode(4, .4, 0.00, 1.00); + Properties::Pointer p_properties(new Properties(0)); + skin_model_part.CreateNewElement("Element3D3N", 901, { 1,2,3 }, p_properties); + skin_model_part.CreateNewElement("Element3D3N", 902, { 1,4,3 }, p_properties); + + std::size_t size = 5; + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(size); + } + + for(std::size_t i = 0 ; i < 3 ; i++){ + for(std::size_t j = 0 ; j < size ; j++) + coordinates[i][j] = static_cast(j)/static_cast(size); + } + + array_1d min_position; + array_1d max_position; + + for(std::size_t i = 0 ; i < 3 ; i++){ + min_position[i] = 0; + max_position[i] = size-1; + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + mesh_colors.InitializeRays(min_position, max_position, "face_of_elements"); + mesh_colors.SetAllColors(1); + + for(auto& element : skin_model_part.Elements()) + { + Element::GeometryType& r_geometry = element.GetGeometry(); + mesh_colors.AddGeometry(r_geometry, false); + } + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + if(coordinates[0][i] >= .4){ + mesh_colors.GetElementalColor(i,j,k) = -2; + } + } + } + } + + mesh_colors.CalculateElementalFaceColors(min_position, max_position, -1, 1, -2); + + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + auto colors = mesh_colors.GetElementalFaceColor(i,j,k); + if(i == 2){ + KRATOS_EXPECT_NEAR(colors[0], -1, 1e-6); + } + else{ + KRATOS_EXPECT_NEAR(colors[0], 1, 1e-6); + } + KRATOS_EXPECT_NEAR(colors[1], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[2], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[3], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[4], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[5], 1, 1e-6); + } + } + } + + } + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsYPlaneFaceColoring, KratosCoreFastSuite) + { + Node::Pointer p_point_1=Kratos::make_intrusive(1, 0.00, .4, 0.00); + Node::Pointer p_point_2=Kratos::make_intrusive(2, 1.00, .4, 0.00); + Node::Pointer p_point_3=Kratos::make_intrusive(3, 1.00, .4, 1.00); + Node::Pointer p_point_4=Kratos::make_intrusive(4, 0.00, .4, 1.00); + + Triangle3D3 triangle_1(p_point_1, p_point_2, p_point_3); + Triangle3D3 triangle_2(p_point_1, p_point_3, p_point_4); + + std::size_t size = 5; + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(size); + } + + for(std::size_t i = 0 ; i < 3 ; i++){ + for(std::size_t j = 0 ; j < size ; j++) + coordinates[i][j] = static_cast(j)/static_cast(size); + } + + array_1d min_position; + array_1d max_position; + + for(std::size_t i = 0 ; i < 3 ; i++){ + min_position[i] = 0; + max_position[i] = size-1; + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + mesh_colors.InitializeRays(min_position, max_position, "face_of_elements"); + mesh_colors.SetAllColors(1); + mesh_colors.AddGeometry(triangle_1,false); + mesh_colors.AddGeometry(triangle_2, false); + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + if(coordinates[1][j] >= .4){ + mesh_colors.GetElementalColor(i,j,k) = -2; + } + } + } + } + + mesh_colors.CalculateElementalFaceColors(min_position, max_position, -1, 1, -2); + + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + auto colors = mesh_colors.GetElementalFaceColor(i,j,k); + if(j == 2){ + KRATOS_EXPECT_NEAR(colors[1], -1, 1e-6); + } + else{ + KRATOS_EXPECT_NEAR(colors[1], 1, 1e-6); + } + KRATOS_EXPECT_NEAR(colors[0], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[2], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[3], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[4], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[5], 1, 1e-6); + } + } + } + + } + + KRATOS_TEST_CASE_IN_SUITE(CartesianMeshColorsZPlaneFaceColoring, KratosCoreFastSuite) + { + Node::Pointer p_point_1=Kratos::make_intrusive(1, 0.00, 0.00, .4); + Node::Pointer p_point_2=Kratos::make_intrusive(2, 1.00, 0.00, .4); + Node::Pointer p_point_3=Kratos::make_intrusive(3, 1.00, 1.00, .4); + Node::Pointer p_point_4=Kratos::make_intrusive(4, 0.00, 1.00, .4); + + Triangle3D3 triangle_1(p_point_1, p_point_2, p_point_3); + Triangle3D3 triangle_2(p_point_1, p_point_3, p_point_4); + + std::size_t size = 5; + Kratos::Internals::CartesianMeshColors mesh_colors; + + array_1d, 3> coordinates; + for(std::size_t i = 0 ; i < 3 ; i++){ + coordinates[i].resize(size); + } + + for(std::size_t i = 0 ; i < 3 ; i++){ + for(std::size_t j = 0 ; j < size ; j++) + coordinates[i][j] = static_cast(j)/static_cast(size); + } + + array_1d min_position; + array_1d max_position; + + for(std::size_t i = 0 ; i < 3 ; i++){ + min_position[i] = 0; + max_position[i] = size-1; + } + + mesh_colors.SetCoordinates(coordinates[0], coordinates[1], coordinates[2]); + mesh_colors.InitializeRays(min_position, max_position, "face_of_elements"); + mesh_colors.SetAllColors(1); + mesh_colors.AddGeometry(triangle_1,false); + mesh_colors.AddGeometry(triangle_2, false); + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + if(coordinates[2][k] >= .4){ + mesh_colors.GetElementalColor(i,j,k) = -2; + } + } + } + } + + mesh_colors.CalculateElementalFaceColors(min_position, max_position, -1, 1, -2); + + + for (std::size_t k = 0; k < size - 1; k++) { + for (std::size_t j = 0; j < size - 1; j++) { + for (std::size_t i = 0; i < size -1; i++) { + auto colors = mesh_colors.GetElementalFaceColor(i,j,k); + if(k == 2){ + KRATOS_EXPECT_NEAR(colors[2], -1, 1e-6); + } + else{ + KRATOS_EXPECT_NEAR(colors[2], 1, 1e-6); + } + KRATOS_EXPECT_NEAR(colors[0], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[1], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[3], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[4], 1, 1e-6); + KRATOS_EXPECT_NEAR(colors[5], 1, 1e-6); + } + } + } + + } + + +} // namespace Kratos::Testing diff --git a/kratos/tests/cpp_tests/strategies/strategies/test_strategies.cpp b/kratos/tests/cpp_tests/strategies/strategies/test_strategies.cpp index 1ef892bc86ad..bd8e3365ae03 100755 --- a/kratos/tests/cpp_tests/strategies/strategies/test_strategies.cpp +++ b/kratos/tests/cpp_tests/strategies/strategies/test_strategies.cpp @@ -227,6 +227,64 @@ namespace Kratos } } + + /** + * Checks if the Nonconvereged solutions of the Newton Rapshon strategy performs correctly + */ + KRATOS_TEST_CASE_IN_SUITE(NonconvergedSolutionsNRStrategy, KratosCoreFastSuite) + { + Model current_model; + + constexpr double tolerance_residual_criteria = 1e-15; // with this tolerance, I expect the strategy to reach the maximum number of iterations, i.e. 10 + + + ModelPart& model_part = current_model.CreateModelPart("Main"); + + SchemeType::Pointer pscheme = SchemeType::Pointer( new ResidualBasedIncrementalUpdateStaticSchemeType() ); + LinearSolverType::Pointer psolver = LinearSolverType::Pointer( new SkylineLUFactorizationSolverType() ); + ConvergenceCriteriaType::Pointer pcriteria = ConvergenceCriteriaType::Pointer( new ResidualCriteriaType(tolerance_residual_criteria, tolerance_residual_criteria) ); + BuilderAndSolverType::Pointer pbuildandsolve = BuilderAndSolverType::Pointer( new ResidualBasedBlockBuilderAndSolverType(psolver) ); + + ResidualBasedNewtonRaphsonStrategyType::Pointer pstrategy = ResidualBasedNewtonRaphsonStrategyType::Pointer( new ResidualBasedNewtonRaphsonStrategyType(model_part, pscheme, pcriteria, pbuildandsolve, 10, true)); + + DofsArrayType Doftemp = BasicTestStrategyDisplacement(model_part, ResidualType::NON_LINEAR); + + NodeType::Pointer pnode = model_part.pGetNode(1); + + double time = 0.0; + const double delta_time = 1.0e-4; + const unsigned int number_iterations = 1; + + pstrategy-> SetUpNonconvergedSolutionsFlag(true); + + for (unsigned int iter = 0; iter < number_iterations; ++iter) { + time += delta_time; + + model_part.CloneTimeStep(time); + + array_1d init_vector; + init_vector[0] = 0.5; + init_vector[1] = 0.5; + init_vector[2] = 0.5; + pnode->FastGetSolutionStepValue(DISPLACEMENT) = init_vector; + + pcriteria->SetEchoLevel(0); + pstrategy->SetEchoLevel(0); + pstrategy->Solve(); + + auto [NonconveregedSolutionsMatrix,Dofs]= pstrategy->GetNonconvergedSolutions(); + + unsigned int expected_rows = Dofs.size(); + unsigned int expected_cols = model_part.GetProcessInfo()[NL_ITERATION_NUMBER] + 1; //+1 because zeroth is included + + KRATOS_CHECK_EQUAL(NonconveregedSolutionsMatrix.size1(), expected_rows); + KRATOS_CHECK_EQUAL(NonconveregedSolutionsMatrix.size2(), expected_cols); + + + } + } + + KRATOS_TEST_CASE_IN_SUITE(LineSearchStrategy, KratosCoreFastSuite) { Model current_model; diff --git a/kratos/tests/test_KratosCore.py b/kratos/tests/test_KratosCore.py index 473151231dd9..dcef643e05bd 100644 --- a/kratos/tests/test_KratosCore.py +++ b/kratos/tests/test_KratosCore.py @@ -91,6 +91,7 @@ import test_find_conditions_neighbours_process import test_calculate_nodal_distance_to_skin_process import test_compute_nodal_gradient_process +import test_voxel_modeler import test_model_part_utils_connectivity_generations # Import modules required for sequential orchestrator test @@ -207,6 +208,9 @@ def AssembleTestSuites(): smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_find_conditions_neighbours_process.TestFindConditionsNeighboursProcess])) smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_calculate_nodal_distance_to_skin_process.TestCalculateNodalDistanceToSkinProcessCoarseSphere])) smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_compute_nodal_gradient_process.TestComputeNodalGradientProcessCoarseSphere])) + smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_voxel_modeler.TestVoxelMeshModeler])) + smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_voxel_modeler.TestOpenStructureVoxelizer])) + smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_voxel_modeler.TestBoundaryConditionVoxelizer])) smallSuite.addTests(KratosUnittest.TestLoader().loadTestsFromTestCases([test_model_part_utils_connectivity_generations.TestModelPartUtilsConnectivityGenerations])) if sympy_available: diff --git a/kratos/tests/test_voxel_modeler.py b/kratos/tests/test_voxel_modeler.py new file mode 100644 index 000000000000..08dbc90262f7 --- /dev/null +++ b/kratos/tests/test_voxel_modeler.py @@ -0,0 +1,829 @@ +import math + +import KratosMultiphysics as kratos +from KratosMultiphysics import KratosUnittest +from KratosMultiphysics.model_parameters_factory import KratosModelParametersFactory + + +def run_modelers(model, settings): + factory = KratosModelParametersFactory(model) + list_of_modelers = factory.ConstructListOfItems(settings) + + for modeler in list_of_modelers: + modeler.SetupGeometryModel() + + for modeler in list_of_modelers: + modeler.PrepareGeometryModel() + + for modeler in list_of_modelers: + modeler.SetupModelPart() + + +class TestVoxelMeshModeler(KratosUnittest.TestCase): + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerNoMdpa(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters("""[{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.01, 0.01, 0.02], + "min_point" : [ 0.02, 0.02, -0.02], + "max_point" : [ 0.04, 0.04, 0.04] + } + }, + "coloring_settings_list": [ + { + "type" : "outer_faces_of_cells_with_color", + "color": -2, + "cell_color": 1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": 1, + "properties_id": 1 + }, + { + "type" : "conditions_with_face_color", + "model_part_name": "main_model_part.workpiece_boundaries", + "color": -2, + "properties_id": 2 + } + + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that elements, nodes and conditions were generated correctly + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 12 ) + self.assertEqual( len(main_model_part.Nodes), 36 ) + self.assertEqual( len(main_model_part.Conditions), 32 ) + + for element in main_model_part.Elements: + self.assertGreaterEqual(element.GetGeometry().Volume(), 0.00) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerElementInput(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + skin_model_part = model[modelers_list[0]["parameters"]["input_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(skin_model_part.Elements), 12 ) + self.assertEqual( len(skin_model_part.Nodes), 8 ) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 8 ) + self.assertEqual( len(main_model_part.Nodes), 27 ) + + for element in main_model_part.Elements: + self.assertGreaterEqual(element.GetGeometry().Volume(), 0.00) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerQuadraticElementInput(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "quadratic_elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + skin_model_part = model[modelers_list[0]["parameters"]["input_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(skin_model_part.Elements), 12 ) + self.assertEqual( len(skin_model_part.Nodes), 8 ) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 8 ) + self.assertEqual( len(main_model_part.Nodes), 125 ) + + expected_volume = 0.03**3 + for element in main_model_part.Elements: + self.assertEqualTolerance(element.GetGeometry().Volume(), expected_volume, 1e-12) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerElementInputAutoSkin(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "type" : "outer_shell", + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + skin_model_part = model[modelers_list[0]["parameters"]["input_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(skin_model_part.Elements), 12 ) + self.assertEqual( len(skin_model_part.Nodes), 8 ) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 8 ) + self.assertEqual( len(main_model_part.Nodes), 27 ) + + for element in main_model_part.Elements: + self.assertGreaterEqual(element.GetGeometry().Volume(), 0.00) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerTetrahedralElementInput(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "tetrahedral_elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + skin_model_part = model[modelers_list[0]["parameters"]["input_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(skin_model_part.Elements), 12 ) + self.assertEqual( len(skin_model_part.Nodes), 8 ) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 48 ) # 8 cells with 6 tetrahedra each + self.assertEqual( len(main_model_part.Nodes), 27 ) + + for element in main_model_part.Elements: + self.assertGreaterEqual(element.GetGeometry().Volume(), 0.00) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerConditionInput(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh_conditions", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1, + "input_entities": "conditions" + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 8 ) + self.assertEqual( len(main_model_part.Nodes), 27 ) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerConnectedElements(self): + + ## create model + model = kratos.Model() + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/un_connected_parts", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [0.00, 0.00, 0.00], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_in_touch", + "model_part_name": "skin_model_part.workpiece", + "color": -1, + "input_entities": "conditions" + }, + { + "type" : "connected_cells_in_touch", + "model_part_name": "skin_model_part.base", + "color": -2, + "cell_color": -1, + "input_entities": "conditions" + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -2, + "properties_id": 1 + }, + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.excluded", + "color": -1, + "properties_id": 2 + } + ] + } + }]""") + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 6 ) + self.assertEqual( len(main_model_part.Nodes), 33 ) + + workpiec_model_part = model["main_model_part.workpiece"] + # Check nb of node and elements + self.assertEqual( len(workpiec_model_part.Elements), 4 ) + self.assertEqual( len(workpiec_model_part.Nodes), 24 ) + + excluded_model_part = model["main_model_part.excluded"] + # Check nb of node and elements + self.assertEqual( len(excluded_model_part.Elements), 2 ) + self.assertEqual( len(excluded_model_part.Nodes), 12 ) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestVoxelMeshModelerInRadius(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/two_particles", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_center_in_sphere_arround_nodes", + "model_part_name": "skin_model_part", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": 1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + skin_model_part_name = modelers_list[0]["parameters"]["input_model_part_name"].GetString() + skin_model_part = model.CreateModelPart(skin_model_part_name) + + skin_model_part.AddNodalSolutionStepVariable(kratos.RADIUS) + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 12 ) + self.assertEqual( len(main_model_part.Nodes), 52 ) + + for element in main_model_part.Elements: + center = element.GetGeometry().Center() + for i in range(1,3): + node = skin_model_part.GetNode(i) + distance_vector = node - center + distance = math.sqrt(sum([x**2 for x in distance_vector])) + radius = node.GetSolutionStepValue(kratos.RADIUS) + self.assertGreater( distance, radius ) + + +class TestOpenStructureVoxelizer(KratosUnittest.TestCase): + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestOpenStructureVoxelizerElementInput(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] } + }, + "coloring_settings_list": [ + { + "type" : "cells_in_touch", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 18 ) + self.assertEqual( len(main_model_part.Nodes), 48 ) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestOpenStructureVoxelizerConditionInput(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh_conditions", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] } + }, + "coloring_settings_list": [ + { + "type" : "cells_in_touch", + "model_part_name": "skin_model_part.workpiece", + "color": -1, + "input_entities": "conditions" + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 18 ) + self.assertEqual( len(main_model_part.Nodes), 48 ) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestFirstCellTouchVoxelizer(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.05,-0.02, 0.04], + "max_point" : [ 0.01, 0.01, 0.07] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_in_touch", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "elements_with_cell_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Elements), 1 ) + self.assertEqual( len(main_model_part.Nodes), 8 ) + + +class TestBoundaryConditionVoxelizer(KratosUnittest.TestCase): + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestWallConditionVoxelizer(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + }, + { + "type" : "cells_faces", + "model_part_name": "skin_model_part.workpiece", + "color": -1, + "cell_color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "conditions_with_face_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Conditions), 24 ) + self.assertEqual( len(main_model_part.Nodes), 26 ) + + for condition in main_model_part.Conditions: + self.assertGreaterEqual(condition.GetGeometry().Area(), 0.00) + + + @KratosUnittest.skipIf(kratos.IsDistributedRun(), "This test is designed for serial runs only.") + def test_TestFacesBetweenColors(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + }, + { + "type" : "cells_faces_between_colors", + "outside_color" : 1.0, + "color": -1, + "cell_color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "conditions_with_face_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Conditions), 8 ) + self.assertEqual( len(main_model_part.Nodes), 15 ) + + for condition in main_model_part.Conditions: + self.assertGreaterEqual(condition.GetGeometry().Area(), 0.00) + + + def test_TestOuterWallConditionVoxelizer(self): + + modelers_list = kratos.Parameters(""" + [{ + "name" : "KratosMultiphysics.VoxelMeshGeneratorModeler", + "parameters" : { + "output_model_part_name" : "main_model_part", + "input_model_part_name" : "skin_model_part", + "mdpa_file_name" : "auxiliar_files_for_python_unittest/voxel_mesh_modeler/cube_skin_mesh", + "key_plane_generator": { + "Parameters" : { + "voxel_sizes" : [0.03, 0.03, 0.03], + "min_point" : [-0.03,-0.03, 0.03], + "max_point" : [ 0.09, 0.09, 0.09] + } + }, + "coloring_settings_list": [ + { + "type" : "cells_with_inside_center", + "model_part_name": "skin_model_part.workpiece", + "color": -1 + }, + { + "type" : "outer_faces_of_cells_with_color", + "color": -1, + "cell_color": -1 + } + ], + "entities_generator_list": [ + { + "type" : "conditions_with_face_color", + "model_part_name": "main_model_part.workpiece", + "color": -1, + "properties_id": 1 + } + ] + } + }]""") + + ## create model + model = kratos.Model() + + # create modeler obj + run_modelers(model, modelers_list) + + # Check that all element have deactivated in ExecuteBeforeSolutionLoop() + main_model_part = model[modelers_list[0]["parameters"]["output_model_part_name"].GetString()] + + # Check nb of node and elements + self.assertEqual( len(main_model_part.Conditions), 24 ) + self.assertEqual( len(main_model_part.Nodes), 26 ) + + for condition in main_model_part.Conditions: + self.assertGreaterEqual(condition.GetGeometry().Area(), 0.00) + + +if __name__ == '__main__': + KratosUnittest.main() diff --git a/scripts/post_install/stub_generation.py b/scripts/post_install/stub_generation.py index 0acf92a7ef29..66752c996d63 100644 --- a/scripts/post_install/stub_generation.py +++ b/scripts/post_install/stub_generation.py @@ -122,7 +122,7 @@ def SetPythonModulesForCppModules(list_of_python_cpp_libs: 'list[KratosPythonCpp for kratos_python_cpp_lib in list_of_python_cpp_libs: if not kratos_python_cpp_lib.IsPythonModuleDefined(): kratos_module_dependent_module_names_dict[kratos_python_cpp_lib] = [] - for match_cpp_lib_import in re.finditer(f"from +{kratos_python_cpp_lib.GetCppLibModule()} +import +\*", lines): + for match_cpp_lib_import in re.finditer(f"from +{kratos_python_cpp_lib.GetCppLibModule()} +import +\\*", lines): kratos_python_cpp_lib.SetPythonModule(file_path) for match_dependent_imports in re.finditer(f"import +([a-zA-Z0-9_.]+)", lines[:match_cpp_lib_import.start()]): kratos_module_dependent_module_names_dict[kratos_python_cpp_lib].append(match_dependent_imports.group(1)) @@ -196,7 +196,6 @@ def Main(): args: 'list[str]' = ["-o", str(kratos_library_path)] for k in list_of_cpp_libs: args.extend(["-p", k.GetCppLibModule()]) - # args.extend(["-p", "Kratos", "-p", ]) options = parse_options(args) generate_stubs(options)