11 #if !defined(KRATOS_VOLUME_SHAPING_PROCESS_H_INCLUDED )
12 #define KRATOS_VOLUME_SHAPING_PROCESS_H_INCLUDED
58 "variable_name": "VOLUME_WEAR",
67 mVariableName = rParameters[
"variable_name"].
GetString();
72 KRATOS_ERROR <<
"trying to set a variable that is not in the model_part - variable name is " << mVariableName << std::endl;
76 Parameters variables = rParameters[
"properties"];
77 for(
auto iter = variables.
begin(); iter != variables.
end(); ++iter) {
79 std::string variable_name = iter.name();
95 KRATOS_ERROR <<
"Value type for Variable: "<<variable_name<<
" not defined";
99 for(
unsigned int i=0;
i<rParameters[
"flags_list"].
size(); ++
i)
153 this->ShapeVolume(mrModelPart);
189 std::string
Info()
const override
191 return "VolumeShapingProcess";
197 rOStream <<
"VolumeShapingProcess";
244 std::vector<Flags> mControlFlags;
248 std::string mVariableName;
250 struct ShapingVariables{
253 double TotalVolumeLoss;
257 std::vector<unsigned int> VisitedNodesIds;
258 std::vector<double> NodalSurface;
259 std::vector<double> NodalVolume;
260 std::vector<double> NodalVolumeLoss;
273 void ShapeVolume(ModelPart& rModelPart)
278 double Tolerance = 1
e-14;
279 unsigned int NumberOfIterations = 5;
282 this->SetVisitedEntities(rModelPart);
284 ShapingVariables Variables;
286 Variables.TotalVolume = this->ComputeTotalVolume(rModelPart);
287 Variables.TotalSurface = this->ComputeTotalSurface(rModelPart);
289 this->ComputeNodalVolumeAndSurface(rModelPart,Variables);
291 Variables.TotalVolumeLoss = this->ComputeVolumeLosses(rModelPart,Variables);
293 Variables.OffsetFactor = 1;
295 double VolumeIncrement = 0;
297 double Ratio = fabs(Variables.TotalVolume-VolumeIncrement/(Variables.TotalVolume-Variables.TotalVolumeLoss));
300 while(++
iteration < NumberOfIterations && ( Ratio < 0.9 || Ratio > 1 ) && Error > Tolerance)
303 this->MoveSurface(rModelPart,Variables);
305 VolumeIncrement = Variables.TotalVolume - this->ComputeTotalVolume(rModelPart);
307 if( VolumeIncrement > 0 )
308 Variables.OffsetFactor*=(1.0-(Variables.TotalVolumeLoss/VolumeIncrement));
310 if( (VolumeIncrement-Variables.TotalVolumeLoss) * Variables.OffsetFactor > 0 )
311 Variables.OffsetFactor*=(-1);
313 Ratio = fabs(Variables.TotalVolume-VolumeIncrement/(Variables.TotalVolume-Variables.TotalVolumeLoss));
315 Error = fabs(Variables.TotalVolumeLoss-VolumeIncrement);
320 this->ResetVisitedEntities(rModelPart);
322 std::cout<<
" Surface shaping perfomed in "<<
iteration<<
" iterations : Error "<<Error<<std::endl;
323 std::cout<<
" TotalVolume "<<Variables.TotalVolume<<
" TotalVolumeLoss "<<Variables.TotalVolumeLoss<<
" VolumeIncrement "<<VolumeIncrement<<std::endl;
332 void MoveSurface(ModelPart& rModelPart,
const ShapingVariables& rVariables)
336 ModelPart::NodesContainerType::iterator it_begin = rModelPart.NodesBegin();
337 int NumberOfNodes = rModelPart.NumberOfNodes();
339 #pragma omp parallel for
340 for (
int i=0;
i<NumberOfNodes; ++
i)
342 ModelPart::NodesContainerType::iterator i_node = it_begin +
i;
343 if(i_node->Is(VISITED)){
344 unsigned int id = rVariables.VisitedNodesIds[i_node->Id()];
345 const array_1d<double,3>& rNormal = i_node->FastGetSolutionStepValue(NORMAL);
346 double& rShrinkFactor = i_node->FastGetSolutionStepValue(SHRINK_FACTOR);
347 double rOffset = -rVariables.OffsetFactor * rShrinkFactor * rVariables.NodalVolumeLoss[id] * rVariables.NodalSurface[id] / (100 * rVariables.TotalVolume * rVariables.TotalSurface);
350 i_node->Coordinates() += rOffset * rNormal;
351 i_node->FastGetSolutionStepValue(DISPLACEMENT) += rOffset * rNormal;
352 i_node->FastGetSolutionStepValue(DISPLACEMENT,1) += rOffset * rNormal;
362 void SetVisitedEntities(ModelPart& rModelPart)
366 this->SetVisitedNodes(rModelPart);
367 this->SetVisitedElements(rModelPart);
376 void ResetVisitedEntities(ModelPart& rModelPart)
380 this->ResetVisitedNodes(rModelPart);
381 this->ResetVisitedElements(rModelPart);
389 void SetVisitedNodes(ModelPart& rModelPart)
393 for(ModelPart::NodesContainerType::iterator i_node = rModelPart.NodesBegin() ; i_node != rModelPart.NodesEnd() ; ++i_node)
395 if(this->MatchControlFlags(*(i_node.base()))){
396 i_node->Set(VISITED,
true);
407 void ResetVisitedNodes(ModelPart& rModelPart)
411 for(ModelPart::NodesContainerType::iterator i_node = rModelPart.NodesBegin() ; i_node != rModelPart.NodesEnd() ; ++i_node)
413 i_node->Set(VISITED,
false);
423 void SetVisitedElements(ModelPart& rModelPart)
427 for(ModelPart::ElementsContainerType::iterator i_elem = rModelPart.ElementsBegin() ; i_elem != rModelPart.ElementsEnd() ; ++i_elem)
429 for(
unsigned int i=0;
i<i_elem->GetGeometry().size(); ++
i)
431 if(this->MatchControlFlags(i_elem->GetGeometry()(
i))){
432 i_elem->Set(VISITED,
true);
445 void ResetVisitedElements(ModelPart& rModelPart)
449 for(ModelPart::ElementsContainerType::iterator i_elem = rModelPart.ElementsBegin() ; i_elem != rModelPart.ElementsEnd() ; ++i_elem)
451 i_elem->Set(VISITED,
false);
460 double ComputeTotalVolume(ModelPart& rModelPart)
464 const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
465 double TotalVolume = 0;
469 ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
470 int NumberOfElements = rModelPart.NumberOfElements();
472 #pragma omp parallel for reduction(+:TotalVolume)
473 for (
int i=0;
i<NumberOfElements; ++
i)
475 ModelPart::ElementsContainerType::iterator i_elem = it_begin +
i;
476 if( i_elem->GetGeometry().Dimension() == 2 && i_elem->Is(VISITED) )
477 TotalVolume += i_elem->GetGeometry().Area();
482 ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
483 int NumberOfElements = rModelPart.NumberOfElements();
485 #pragma omp parallel for reduction(+:TotalVolume)
486 for (
int i=0;
i<NumberOfElements; ++
i)
488 ModelPart::ElementsContainerType::iterator i_elem = it_begin +
i;
489 if( i_elem->GetGeometry().Dimension() == 3 && i_elem->Is(VISITED) )
490 TotalVolume += i_elem->GetGeometry().Volume();
504 double ComputeTotalSurface(ModelPart& rModelPart)
508 const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
509 double TotalSurface = 0;
513 ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
514 int NumberOfElements = rModelPart.NumberOfElements();
516 #pragma omp parallel for reduction(+:TotalSurface)
517 for (
int i=0;
i<NumberOfElements; ++
i)
519 ModelPart::ElementsContainerType::iterator i_elem = it_begin +
i;
521 if( rGeometry.Dimension() == 2 && i_elem->Is(VISITED) ){
522 for(
unsigned int j=0;
j<rGeometry.size()-1; ++
j)
524 if(rGeometry[
j].
Is(VISITED)){
525 for(
unsigned int k=
j+1;
k<rGeometry.size(); ++
k)
527 if(rGeometry[
k].
Is(VISITED)){
528 TotalSurface +=
norm_2( rGeometry[
k].Coordinates() - rGeometry[
j].Coordinates() );
539 DenseMatrix<unsigned int> lpofa;
540 DenseVector<unsigned int> lnofa;
542 ModelPart::ElementsContainerType::iterator it_begin = rModelPart.ElementsBegin();
543 int NumberOfElements = rModelPart.NumberOfElements();
545 #pragma omp parallel for private(lpofa,lnofa) reduction(+:TotalSurface)
546 for (
int i=0;
i<NumberOfElements; ++
i)
548 ModelPart::ElementsContainerType::iterator i_elem = it_begin +
i;
552 if( rGeometry.Dimension() == 3 && i_elem->Is(VISITED) ){
555 rGeometry.NumberNodesInFaces(lnofa);
557 for(
unsigned int iface=0; iface<rGeometry.FacesNumber(); ++iface)
559 unsigned int free_surface = 0;
560 for(
unsigned int j=1;
j<=lnofa[iface]; ++
j)
561 if(rGeometry[
j].
Is(VISITED))
564 if(free_surface==lnofa[iface])
565 TotalSurface+=Compute3DArea(rGeometry[lpofa(1,iface)].Coordinates(),
566 rGeometry[lpofa(2,iface)].Coordinates(),
567 rGeometry[lpofa(3,iface)].Coordinates());
583 void ComputeNodalVolumeAndSurface(ModelPart& rModelPart, ShapingVariables& rVariables)
588 rVariables.VisitedNodesIds.resize(MaxNodeId+1);
589 std::fill( rVariables.VisitedNodesIds.begin(), rVariables.VisitedNodesIds.end(), 0 );
591 std::vector<GlobalPointersVector<Element> > Neighbours(rModelPart.NumberOfNodes()+1);
593 for(ModelPart::ElementsContainerType::iterator i_elem = rModelPart.ElementsBegin(); i_elem!=rModelPart.ElementsEnd(); ++i_elem)
595 if(i_elem->Is(VISITED)){
599 for(
unsigned int i = 0;
i < pGeometry.size(); ++
i)
601 if( pGeometry[
i].
Is(VISITED) ){
603 if(rVariables.VisitedNodesIds[pGeometry[
i].Id()]==0){
604 rVariables.VisitedNodesIds[pGeometry[
i].Id()]=id;
605 Neighbours[id].push_back( Element::WeakPointer( *(i_elem.base()) ) );
609 Neighbours[rVariables.VisitedNodesIds[pGeometry[
i].Id()]].push_back( Element::WeakPointer( *(i_elem.base()) ) );
617 rVariables.NodalSurface.resize(
id);
618 std::fill( rVariables.NodalSurface.begin(), rVariables.NodalSurface.end(), 0 );
620 rVariables.NodalVolume.resize(
id);
621 std::fill( rVariables.NodalVolume.begin(), rVariables.NodalVolume.end(), 0 );
623 const unsigned int dimension = rModelPart.GetProcessInfo()[SPACE_DIMENSION];
627 ModelPart::NodesContainerType::iterator it_begin = rModelPart.NodesBegin();
628 int NumberOfNodes = rModelPart.NumberOfNodes();
630 #pragma omp parallel for
631 for (
int i=0;
i<NumberOfNodes; ++
i)
633 ModelPart::NodesContainerType::iterator i_node = it_begin +
i;
635 if( i_node->Is(VISITED) ){
636 unsigned int id = rVariables.VisitedNodesIds[i_node->Id()];
637 GlobalPointersVector<Element>& rE = Neighbours[id];
642 rVariables.NodalVolume[id] += ie->GetGeometry().
Area() /
double(ie->GetGeometry().size());
644 if( rGeometry.Dimension() == 2 ){
645 for(
unsigned int j=0;
j<rGeometry.size()-1; ++
j)
647 if(rGeometry[
j].
Is(VISITED)){
648 for(
unsigned int k=
j+1;
k<rGeometry.size(); ++
k)
650 if(rGeometry[
k].
Is(VISITED) && (rGeometry[
j].Id() == i_node->Id() || rGeometry[
k].Id() == i_node->Id()) ){
651 rVariables.NodalSurface[id] += 0.5 *
norm_2( rGeometry[
k].Coordinates() - rGeometry[
j].Coordinates() );
663 DenseMatrix<unsigned int> lpofa;
664 DenseVector<unsigned int> lnofa;
666 ModelPart::NodesContainerType::iterator it_begin = rModelPart.NodesBegin();
667 int NumberOfNodes = rModelPart.NumberOfNodes();
669 double athird = 1.0/3.0;
671 #pragma omp parallel for private(lpofa,lnofa)
672 for (
int i=0;
i<NumberOfNodes; ++
i)
674 ModelPart::NodesContainerType::iterator i_node = it_begin +
i;
676 if( i_node->Is(VISITED) ){
677 unsigned int id = rVariables.VisitedNodesIds[i_node->Id()];
678 GlobalPointersVector<Element>& rE = Neighbours[id];
683 rVariables.NodalVolume[id] += ie->GetGeometry().
Volume() /
double(ie->GetGeometry().size());
685 if( rGeometry.Dimension() == 3 ){
687 rGeometry.NodesInFaces(lpofa);
688 rGeometry.NumberNodesInFaces(lnofa);
690 for(
unsigned int iface=0; iface<rGeometry.FacesNumber(); ++iface)
692 unsigned int visited = 0;
693 bool selected =
false;
694 for(
unsigned int j=1;
j<=lnofa[iface]; ++
j){
695 if(rGeometry[
j].
Is(VISITED))
697 if(rGeometry[
i].Id() == i_node->Id())
701 if(visited==lnofa[iface] && selected)
702 rVariables.NodalSurface[id]+= athird * Compute3DArea(rGeometry[lpofa(1,iface)].Coordinates(),
703 rGeometry[lpofa(2,iface)].Coordinates(),
704 rGeometry[lpofa(3,iface)].Coordinates());
721 double ComputeVolumeLosses(ModelPart& rModelPart, ShapingVariables& rVariables)
725 double TotalVolumeLoss = 0;
727 const Variable<double>& VolumeLossVariable = KratosComponents< Variable<double> >::Get(mVariableName);
729 double ArchardCoefficient = 0;
730 if( mProperties.
Has(WEAR_COEFFICIENT) && mProperties.
Has(INDENTATION_HARDNESS) ){
731 ArchardCoefficient = mProperties[WEAR_COEFFICIENT] / mProperties[INDENTATION_HARDNESS];
734 KRATOS_WARNING(
"Wear calculation not possible") <<
" WEAR_COEFFICIENT and INDENTATION_HARDNESS variables not DEFINED " << std::endl;
737 ModelPart::NodesContainerType::iterator it_begin = rModelPart.NodesBegin();
738 int NumberOfNodes = rModelPart.NumberOfNodes();
740 rVariables.NodalVolumeLoss.resize(rVariables.NodalVolume.size());
741 std::fill( rVariables.NodalVolumeLoss.begin(), rVariables.NodalVolumeLoss.end(), 0 );
743 #pragma omp parallel for reduction(+:TotalVolumeLoss)
744 for (
int i=0;
i<NumberOfNodes; ++
i)
746 ModelPart::NodesContainerType::iterator i_node = it_begin +
i;
748 unsigned int id = rVariables.VisitedNodesIds[i_node->Id()];
749 if( i_node->Is(VISITED) &&
id != 0 ){
751 const array_1d<double,3>& Normal = i_node->FastGetSolutionStepValue(NORMAL);
752 const array_1d<double,3>& ContactForce = i_node->FastGetSolutionStepValue(CONTACT_FORCE);
754 array_1d<double,3> DeltaDisplacement = i_node->FastGetSolutionStepValue(DISPLACEMENT) - i_node->FastGetSolutionStepValue(DISPLACEMENT,1);
756 rVariables.NodalVolumeLoss[id] = ArchardCoefficient * fabs(
inner_prod(ContactForce,Normal)) *
norm_2( DeltaDisplacement -
inner_prod(DeltaDisplacement,Normal) * Normal);
758 i_node->FastGetSolutionStepValue(VolumeLossVariable) += rVariables.NodalVolumeLoss[id];
760 if( rVariables.NodalVolumeLoss[
id] > rVariables.NodalVolume[
id] )
761 rVariables.NodalVolumeLoss[id] = rVariables.NodalVolume[id];
763 TotalVolumeLoss += rVariables.NodalVolumeLoss[id];
768 return TotalVolumeLoss;
778 bool MatchControlFlags(
const Node::Pointer& pNode)
781 for(
unsigned int i = 0;
i<mControlFlags.size();
i++)
783 if( pNode->IsNot(mControlFlags[
i]) )
792 double Compute3DArea(array_1d<double,3> PointA, array_1d<double,3> PointB, array_1d<double,3> PointC){
796 double s = (
a+
b+
c) / 2.0;
797 double Area=std::sqrt(s*(s-
a)*(s-
b)*(s-
c));
851 rOStream << std::endl;
Base class for all Conditions.
Definition: condition.h:59
Geometry< NodeType > GeometryType
definition of the geometry type with given NodeType
Definition: element.h:83
bool Is(Flags const &rOther) const
Definition: flags.h:274
Geometry base class.
Definition: geometry.h:71
virtual void NodesInFaces(DenseMatrix< unsigned int > &rNodesInFaces) const
Definition: geometry.h:2195
virtual double Volume() const
This method calculate and return volume of this geometry.
Definition: geometry.h:1358
virtual double Area() const
This method calculate and return area or surface area of this geometry depending to it's dimension.
Definition: geometry.h:1345
boost::indirect_iterator< typename TContainerType::iterator > iterator
Definition: global_pointers_vector.h:79
KratosComponents class encapsulates a lookup table for a family of classes in a generic way.
Definition: kratos_components.h:49
static double Norm3(const TVectorType &a)
Calculates the norm of vector "a" which is assumed to be of size 3.
Definition: math_utils.h:691
static unsigned int GetMaxNodeId(ModelPart &rModelPart)
Definition: mesher_utilities.hpp:1408
This class aims to manage meshes for multi-physics simulations.
Definition: model_part.h:77
VariablesList & GetNodalSolutionStepVariablesList()
Definition: model_part.h:549
This class defines the node.
Definition: node.h:65
This class provides to Kratos a data structure for I/O based on the standard of JSON.
Definition: kratos_parameters.h:59
Parameters GetValue(const std::string &rEntry)
This method returns the Parameter corresponding to a certain entry.
Definition: kratos_parameters.cpp:423
iterator begin()
This returns the begin iterator.
Definition: kratos_parameters.cpp:961
double GetDouble() const
This method returns the double contained in the current Parameter.
Definition: kratos_parameters.cpp:657
iterator end()
This returns the end iterator.
Definition: kratos_parameters.cpp:969
int GetInt() const
This method returns the integer contained in the current Parameter.
Definition: kratos_parameters.cpp:666
void ValidateAndAssignDefaults(const Parameters &rDefaultParameters)
This function is designed to verify that the parameters under testing match the form prescribed by th...
Definition: kratos_parameters.cpp:1306
SizeType size() const
This method returns the total size of the current array parameter.
Definition: kratos_parameters.cpp:993
std::string GetString() const
This method returns the string contained in the current Parameter.
Definition: kratos_parameters.cpp:684
bool GetBool() const
This method returns the boolean contained in the current Parameter.
Definition: kratos_parameters.cpp:675
The base class for all processes in Kratos.
Definition: process.h:49
Properties encapsulates data shared by different Elements or Conditions. It can store any type of dat...
Definition: properties.h:69
bool Has(TVariableType const &rThisVariable) const
Definition: properties.h:578
void SetValue(TVariableType const &rV, typename TVariableType::Type const &rValue)
Definition: properties.h:287
bool Has(const VariableData &rThisVariable) const
Definition: variables_list.h:372
Move free surface to restore volume losses.
Definition: volume_shaping_process.hpp:34
void ExecuteBeforeOutputStep() override
this function will be executed at every time step BEFORE writing the output
Definition: volume_shaping_process.hpp:160
void ExecuteFinalizeSolutionStep() override
this function will be executed at every time step AFTER performing the solve phase
Definition: volume_shaping_process.hpp:148
void ExecuteAfterOutputStep() override
this function will be executed at every time step AFTER writing the output
Definition: volume_shaping_process.hpp:166
ConditionType::GeometryType GeometryType
Definition: volume_shaping_process.hpp:45
void ExecuteInitialize() override
Definition: volume_shaping_process.hpp:132
ModelPart::ConditionType ConditionType
Definition: volume_shaping_process.hpp:43
ModelPart::PropertiesType PropertiesType
Definition: volume_shaping_process.hpp:44
std::string Info() const override
Turn back information as a string.
Definition: volume_shaping_process.hpp:189
void ExecuteFinalize() override
Definition: volume_shaping_process.hpp:173
void PrintInfo(std::ostream &rOStream) const override
Print information about this object.
Definition: volume_shaping_process.hpp:195
VolumeShapingProcess(ModelPart &rModelPart, Parameters rParameters)
Default constructor.
Definition: volume_shaping_process.hpp:52
void ExecuteBeforeSolutionLoop() override
Definition: volume_shaping_process.hpp:138
void Execute() override
Execute method is used to execute the AssignPropertiesToNodesProcess algorithms.
Definition: volume_shaping_process.hpp:126
void ExecuteInitializeSolutionStep() override
this function will be executed at every time step BEFORE performing the solve phase
Definition: volume_shaping_process.hpp:143
virtual ~VolumeShapingProcess()
Destructor.
Definition: volume_shaping_process.hpp:108
KRATOS_CLASS_POINTER_DEFINITION(VolumeShapingProcess)
Pointer definition of Process.
ModelPart::NodeType NodeType
Definition: volume_shaping_process.hpp:42
void PrintData(std::ostream &rOStream) const override
Print object's data.s.
Definition: volume_shaping_process.hpp:201
void operator()()
This operator is provided to call the process as a function and simply calls the Execute method.
Definition: volume_shaping_process.hpp:116
#define KRATOS_CATCH(MoreInfo)
Definition: define.h:110
#define KRATOS_TRY
Definition: define.h:109
#define KRATOS_ERROR
Definition: exception.h:161
#define KRATOS_WARNING(label)
Definition: logger.h:265
iteration
Definition: DEM_benchmarks.py:172
bool Has(const std::string &ModelerName)
Checks if the modeler is registered.
Definition: modeler_factory.cpp:24
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
TExpressionType::data_type norm_2(AMatrix::MatrixExpression< TExpressionType, TCategory > const &TheExpression)
Definition: amatrix_interface.h:625
TExpression1Type::data_type inner_prod(AMatrix::MatrixExpression< TExpression1Type, TCategory1 > const &First, AMatrix::MatrixExpression< TExpression2Type, TCategory2 > const &Second)
Definition: amatrix_interface.h:592
std::istream & operator>>(std::istream &rIStream, LinearMasterSlaveConstraint &rThis)
input stream function
TABLE_NUMBER_ANGULAR_VELOCITY TABLE_NUMBER_MOMENT I33 BEAM_INERTIA_ROT_UNIT_LENGHT_Y KRATOS_DEFINE_APPLICATION_VARIABLE(DEM_APPLICATION, double, BEAM_INERTIA_ROT_UNIT_LENGHT_Z) typedef std double
Definition: DEM_application_variables.h:182
std::ostream & operator<<(std::ostream &rOStream, const LinearMasterSlaveConstraint &rThis)
output stream function
Definition: linear_master_slave_constraint.h:432
a
Definition: generate_stokes_twofluid_element.py:77
b
Definition: generate_total_lagrangian_mixed_volumetric_strain_element.py:31
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
int dimension
Definition: isotropic_damage_automatic_differentiation.py:123
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
integer i
Definition: TensorModule.f:17
e
Definition: run_cpp_mpi_tests.py:31