-
Notifications
You must be signed in to change notification settings - Fork 261
[GeoMechanicsApplication] Include variable prediction in all newmark schemes #13449
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
[GeoMechanicsApplication] Include variable prediction in all newmark schemes #13449
Conversation
…ot fixed (and changed other tests accordingly)
…ixed + formatting
void PredictVariables(const ModelPart& rModelPart) | ||
{ | ||
block_for_each(rModelPart.Nodes(), [this](Node& rNode) { PredictVariablesForNode(rNode); }); | ||
} | ||
|
||
void PredictVariablesForNode(Node& rNode) | ||
{ | ||
for (const auto& r_first_order_scalar_variable : this->GetFirstOrderScalarVariables()) { | ||
if (!rNode.SolutionStepsDataHas(r_first_order_scalar_variable.instance)) continue; | ||
PredictFirstOrderScalarVariableForNode(rNode, r_first_order_scalar_variable); | ||
} | ||
|
||
for (const auto& r_second_order_vector_variable : this->GetSecondOrderVectorVariables()) { | ||
if (!rNode.SolutionStepsDataHas(r_second_order_vector_variable.instance)) continue; | ||
PredictSecondOrderVectorVariableForNode(rNode, r_second_order_vector_variable); | ||
} | ||
} | ||
|
||
void PredictFirstOrderScalarVariableForNode(Node& rNode, const FirstOrderScalarVariable& rFirstOrderScalarVariable) | ||
{ | ||
const double previous_variable = | ||
rNode.FastGetSolutionStepValue(rFirstOrderScalarVariable.instance, 1); | ||
const double previous_first_time_derivative = | ||
rNode.FastGetSolutionStepValue(rFirstOrderScalarVariable.first_time_derivative, 1); | ||
const double current_first_time_derivative = | ||
rNode.FastGetSolutionStepValue(rFirstOrderScalarVariable.first_time_derivative, 0); | ||
|
||
if (rNode.IsFixed(rFirstOrderScalarVariable.first_time_derivative)) { | ||
rNode.FastGetSolutionStepValue(rFirstOrderScalarVariable.instance) = | ||
previous_variable + (1 - this->GetTheta()) * this->GetDeltaTime() * previous_first_time_derivative + | ||
current_first_time_derivative * this->GetTheta() * this->GetDeltaTime(); | ||
} else if (!rNode.IsFixed(rFirstOrderScalarVariable.instance)) { | ||
rNode.FastGetSolutionStepValue(rFirstOrderScalarVariable.instance) = | ||
previous_variable + this->GetDeltaTime() * previous_first_time_derivative; | ||
} | ||
} | ||
|
||
void PredictSecondOrderVectorVariableForNode(Node& rNode, const SecondOrderVectorVariable& rSecondOrderVectorVariable) | ||
{ | ||
const std::vector<std::string> components = {"X", "Y", "Z"}; | ||
|
||
for (const auto& component : components) { | ||
const auto& instance_component = VariablesUtilities::GetComponentFromVectorVariable( | ||
rSecondOrderVectorVariable.instance.Name(), component); | ||
|
||
if (!rNode.HasDofFor(instance_component)) continue; | ||
|
||
const auto& first_time_derivative_component = VariablesUtilities::GetComponentFromVectorVariable( | ||
rSecondOrderVectorVariable.first_time_derivative.Name(), component); | ||
const auto& second_time_derivative_component = VariablesUtilities::GetComponentFromVectorVariable( | ||
rSecondOrderVectorVariable.second_time_derivative.Name(), component); | ||
|
||
const double previous_variable = rNode.FastGetSolutionStepValue(instance_component, 1); | ||
const double current_first_time_derivative = | ||
rNode.FastGetSolutionStepValue(first_time_derivative_component, 0); | ||
const double previous_first_time_derivative = | ||
rNode.FastGetSolutionStepValue(first_time_derivative_component, 1); | ||
const double current_second_time_derivative = | ||
rNode.FastGetSolutionStepValue(second_time_derivative_component, 0); | ||
const double previous_second_time_derivative = | ||
rNode.FastGetSolutionStepValue(second_time_derivative_component, 1); | ||
if (rNode.IsFixed(second_time_derivative_component)) { | ||
rNode.FastGetSolutionStepValue(instance_component) = | ||
previous_variable + this->GetDeltaTime() * previous_first_time_derivative + | ||
this->GetDeltaTime() * this->GetDeltaTime() * | ||
((0.5 - this->GetBeta()) * previous_second_time_derivative + | ||
this->GetBeta() * current_second_time_derivative); | ||
} else if (rNode.IsFixed(first_time_derivative_component)) { | ||
rNode.FastGetSolutionStepValue(instance_component) = | ||
previous_variable + | ||
this->GetDeltaTime() * ((this->GetBeta() / this->GetGamma()) * | ||
(current_first_time_derivative - previous_first_time_derivative) + | ||
previous_first_time_derivative); | ||
} else if (!rNode.IsFixed(instance_component)) { | ||
rNode.FastGetSolutionStepValue(instance_component) = | ||
previous_variable + this->GetDeltaTime() * previous_first_time_derivative + | ||
0.5 * this->GetDeltaTime() * this->GetDeltaTime() * previous_second_time_derivative; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Most of this just moved from the dynamic scheme, the only new part is the PredictFirstOrderScalarVariableForNode
function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Richard, I think it was difficult to spot such a thing. I have only a comment on Predict
function's description in common_strategies\schemes\README.md. Shall it be updated?
for (const auto& r_second_order_vector_variable : this->GetSecondOrderVectorVariables()) { | ||
if (!rNode.SolutionStepsDataHas(r_second_order_vector_variable.instance)) continue; | ||
PredictSecondOrderVectorVariableForNode(rNode, r_second_order_vector_variable); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@WPK4FEM should I move this part (for the SecondOrderVectorVariables
) back to the dynamic version of the newmark scheme, since only there we have non-zero accelerations/velocities?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, at least the part for acceleration.
The newmark_quasistatic_damped_U_Pw_scheme has no acceleration, but has velocities and a damping matrix, so would have a Predict without accelerations, but with prescribed velocities.
Good catch, I'll update the README |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi, i hope you don't mind if i chime in in this conversation.
in order for the Predict to work correctly, we need to guarantee consistency between the DISPLACEMENT, VELOCITY and ACCELERATION (i'll focus my the case on standard solid elements...of course this can be expanded to ROTATION, ANGULAR_VELOCITY and ANGULAR_ACCELERATION if needed.
the point is that the standard "Update" method, called after every system solution guarantees that the VELOCITY and ACCELERATION are updated in accordance to the provided DISPLACEMENT.
One way to undersand the "Predict" is to consider it as a "cheap approximation of a Solve", that is, the Predict provides an approximation to the end of step DISPLACEMENT from which VEL and ACC can be computed consistently.
Such approximation is exact where the DISPLACEMENT is Fixed (dirichlet constraint).
The problem comes when one wants to impose VELOCITY or ACCELERATION as a fixed value instead of the DISPLACEMENT. The current method does not support this, "as is".
In my opinion the correct way of handling this is to guarantee that when the VELOCITY or the ACCELERATION is fixed the DISPLACEMENT is also fixed automaticially, even if not done in the input (of course we will need to unfix it in the InitializeSolutionStep when fixing it automatically). The DISPLACEMENT on the automatically fixed dofs should then be provided the value that guarantees that the desired value of ACCELERATION and/or VELOCITY is obtained.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, looking into the PR i think my comment should have been shorter:
"artificially fix DISPLACEMENT_" whenever you want to fix "VELOCITY_" or "ACCELERATION_*" and then simply apply call "Update"
(and then unfix the list of dofs you fix this way in the FinalizeSolutionStep)
i cannot say if the formulas you are using for the applied displacement are the correct ones ... but provided that they are, this should work
…ict displacements based on its derivatives (only water pressure)
Thanks for your comment, indeed at this point we need to fix the displacement dof manually when we want to fix the velocity or acceleration. This was also what was missing in our prescribed derivatives tests that were failing before when changing the order of We now improved that test by manually fixing displacements (see #13478 if you're interested), which is why we don't see any issues anymore in our test suite with switching the order of At some point indeed it would be nice to be able to automatically fix displacements when prescribing its (second) derivative, but for now this is good enough for us |
…ariable-prediction-in-all-newmark-schemes
📝 Description
This PR adds prediction to all Newmark schemes, both for vector as well as scalar variables.