Skip to content
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

[IgaApplication] Add Nurbs modeler for SBM #13009

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ namespace Kratos
///@name Private Operations
///@{
void NurbsGeometryModeler::CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz,
const Point& A_uvw, const Point& B_uvw, SizeType OrderU, SizeType OrderV,SizeType NumKnotSpansU, SizeType NumKnotSpansV)
const Point& A_uvw, const Point& B_uvw, SizeType OrderU, SizeType OrderV,SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part)
{
KRATOS_ERROR_IF( B_xyz.X() <= A_xyz.X() || B_xyz.Y() <= A_xyz.Y() ) << "NurbsGeometryModeler: "
<< "The two Points A_xyz and B_xyz must meet the following requirement: (B_xyz-A_xyz) > (0,0,0). However, (B_xyz-A_xyz)=" << B_xyz-A_xyz << std::endl;
Expand Down Expand Up @@ -175,22 +175,25 @@ namespace Kratos

// Set up weights. Required in case no refinement is performed.
Vector WeightsRefined(points.size(),1.0);

// Add geometry to model part
if( mParameters.Has("geometry_name") ){
p_surface_geometry->SetId(mParameters["geometry_name"].GetString());
} else {
const SizeType number_of_geometries = r_model_part.NumberOfGeometries();
SizeType last_geometry_id = 0;
if( number_of_geometries > 0 ){
for( auto it = r_model_part.GeometriesBegin(); it!= r_model_part.GeometriesEnd(); ++it){
last_geometry_id = it->Id();

// In some cases there is no need of add the surface geometry, add_surface_to_model_part is true by default
if (add_surface_to_model_part) {
// Add geometry to model part
if( mParameters.Has("geometry_name") ){
p_surface_geometry->SetId(mParameters["geometry_name"].GetString());
} else {
const SizeType number_of_geometries = r_model_part.NumberOfGeometries();
SizeType last_geometry_id = 0;
if( number_of_geometries > 0 ){
for( auto it = r_model_part.GeometriesBegin(); it!= r_model_part.GeometriesEnd(); ++it){
last_geometry_id = it->Id();
}
}
Comment on lines +185 to 191
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const SizeType number_of_geometries = r_model_part.NumberOfGeometries();
SizeType last_geometry_id = 0;
if( number_of_geometries > 0 ){
for( auto it = r_model_part.GeometriesBegin(); it!= r_model_part.GeometriesEnd(); ++it){
last_geometry_id = it->Id();
}
}
const SizeType last_geometry_id = r_model_part.NumberOfGeometries()
? r_model_part.Geometries().Geometries().back().Id()
: 0;

I know, it looks stupid. In fact, it is stupid, but only because the geometry container is still weird.

p_surface_geometry->SetId(last_geometry_id+1);
}
p_surface_geometry->SetId(last_geometry_id+1);
r_model_part.AddGeometry(p_surface_geometry);
}
r_model_part.AddGeometry(p_surface_geometry);


// Perform knot refinement.
PointerVector<NodeType> PointsRefined = p_surface_geometry->Points();
if( NumKnotSpansU > 1) {
Expand Down Expand Up @@ -237,6 +240,13 @@ namespace Kratos
p_surface_geometry->SetInternals(PointsRefined,
p_surface_geometry->PolynomialDegreeU(), p_surface_geometry->PolynomialDegreeV(),
p_surface_geometry->KnotsU(), p_surface_geometry->KnotsV(), WeightsRefined);

// assign the value p_surface_geometry to the class member mpSurface for derived classes
mpSurface = p_surface_geometry;
mInsertKnotsU = insert_knots_u;
mInsertKnotsV = insert_knots_v;
mKnotVectorU = knot_vector_u;
mKnotVectorV = knot_vector_v;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ class KRATOS_API(IGA_APPLICATION) NurbsGeometryModeler
}

/// Destructor.
virtual ~NurbsGeometryModeler() = default;
~NurbsGeometryModeler() = default;

/// Creates the Modeler Pointer
Modeler::Pointer Create(Model& rModel, const Parameters ModelParameters) const override
Expand All @@ -82,15 +82,8 @@ class KRATOS_API(IGA_APPLICATION) NurbsGeometryModeler

///@}

private:
///@name Private Member Variables
///@{

Model* mpModel;

///@}
///@name Private Operations
///@{
protected:
///@{

/**
* @brief Creates a regular grid composed out of bivariant B-splines.
Expand All @@ -100,8 +93,26 @@ class KRATOS_API(IGA_APPLICATION) NurbsGeometryModeler
* @param NumKnotSpans Number of equidistant elements/knot spans in each direction u,v.
* @note The CP'S are defined as nodes and added to the rModelPart.
**/
void CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz, const Point& A_uvw, const Point& B_uvw,
SizeType OrderU, SizeType OrderV, SizeType NumKnotSpansU, SizeType NumKnotSpansV );
virtual void CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz, const Point& A_uvw, const Point& B_uvw,
SizeType OrderU, SizeType OrderV, SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part = true);

Comment on lines +96 to +98
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a lot of arguments, and the docstring seems to be wildly out of date. Please update it and write a @param entry for each argument with some explanations.

Oh and please pick a naming format and stick with it. I suggest the one in the kratos style guide if you don't want the technical committee get mad at you. It would also help you avoid @loumalouomega reformatting your code.

NurbsSurfaceGeometryPointerType mpSurface;

Vector mKnotVectorU;
Vector mKnotVectorV;
std::vector<double> mInsertKnotsU;
std::vector<double> mInsertKnotsV;


private:
///@name Private Member Variables
///@{
Comment on lines +108 to +109
Copy link
Contributor

@matekelemen matekelemen Feb 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just an FYI on doxygen annotations:

  • no doxygen docs are generated for private members, so there's no point marking these sections. Of course commenting the purpose of private members is still good practice but it will only be visible in the code, and not the docs.
  • doxygen automatically detects and highlights the visibility (public/protected/private) of members so again: there's no point in doing section annontations.


Model* mpModel;

///@}
///@name Private Operations


/**
* @brief Creates a cartesian grid composed out of trivariant B-spline cubes.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// | / |
// ' / __| _` | __| _ \ __|
// . \ | ( | | ( |\__ `
// _|\_\_| \__,_|\__|\___/ ____/
// Multi-Physics
//
// License: BSD License
// Kratos default license: kratos/license.txt
//
// Main authors: Nicolo' Antonelli
// Andrea Gorgi
//

// Project includes
#include "nurbs_geometry_modeler_sbm.h"
#include "custom_utilities/create_breps_sbm_utilities.h"
#include "utilities/nurbs_utilities/snake_sbm_utilities.h"

namespace Kratos
{

///@name Stages
///@{

void NurbsGeometryModelerSbm::SetupGeometryModel(){

//----------------------------------------------------------------------------------------------------------------
KRATOS_INFO_IF("NurbsGeometryModelerSbm", mEchoLevel > 1) << "[NURBS MODELER SBM]:: calling NurbsGeometryModeler" << std::endl;

// Call the SetupGeometryModel method of the base class NurbsGeometryModeler
NurbsGeometryModeler::SetupGeometryModel();
}

///@}
///@name Private Operations
///@{
void NurbsGeometryModelerSbm::CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz,
const Point& A_uvw, const Point& B_uvw, SizeType OrderU, SizeType OrderV,SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part)
Comment on lines +37 to +38
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this is an override of a virtual member. If so, mark it as such. Also, you can use the @copydoc doxygen command to pull in the annotations from the base class.

Suggested change
void NurbsGeometryModelerSbm::CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz,
const Point& A_uvw, const Point& B_uvw, SizeType OrderU, SizeType OrderV,SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part)
/// @copydoc NurbsGeometryModeler::CreateAndAddRegularGrid2D
void NurbsGeometryModelerSbm::CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz,
const Point& A_uvw, const Point& B_uvw, SizeType OrderU, SizeType OrderV,SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part) override

+ same comment about variable naming in general.

{

// Call the CreateAndAddRegularGrid2D method of the base class NurbsGeometryModeler
NurbsGeometryModeler::CreateAndAddRegularGrid2D(r_model_part, A_xyz, B_xyz,
A_uvw, B_uvw, OrderU, OrderV, NumKnotSpansU, NumKnotSpansV, false);

// Create the Domain/Iga Model Part
const std::string iga_model_part_name = mParameters["model_part_name"].GetString();
ModelPart& iga_model_part = mpModel->HasModelPart(iga_model_part_name)
? mpModel->GetModelPart(iga_model_part_name)
: mpModel->CreateModelPart(iga_model_part_name);

// Create the True Model Part -> contains all the true boundary features
std::string skin_model_part_inner_initial_name = "skin_model_part_inner_initial_name";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouls it be useful to set this name from the json file?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually the "default" name which is overwritten few lines below if the "skin_model_part_inner_inner_initial_name" is provided in the json file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Json defaults should automatically handle this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you suggest us an example to start form for the json defaults? @rubenzorrilla

std::string skin_model_part_outer_initial_name = "skin_model_part_outer_initial_name";
std::string skin_model_part_name;
if (mParameters.Has("skin_model_part_inner_initial_name")) {
skin_model_part_inner_initial_name = mParameters["skin_model_part_inner_initial_name"].GetString();

KRATOS_ERROR_IF_NOT(mpModel->HasModelPart(skin_model_part_inner_initial_name))
<< "The skin_model_part '" << skin_model_part_inner_initial_name << "' was not created in the model.\n"
<< "Check the reading of the mdpa file in the import mdpa modeler."<< std::endl;
}
if (mParameters.Has("skin_model_part_outer_initial_name")) {
skin_model_part_outer_initial_name = mParameters["skin_model_part_outer_initial_name"].GetString();

KRATOS_ERROR_IF_NOT(mpModel->HasModelPart(skin_model_part_outer_initial_name))
<< "The skin_model_part '" << skin_model_part_outer_initial_name << "' was not created in the model.\n"
<< "Check the reading of the mdpa file in the import mdpa modeler."<< std::endl;
}
// If there is not neither skin_inner nor skin_outer throw an error since you are using the sbm modeler
if (!(mParameters.Has("skin_model_part_inner_initial_name") || mParameters.Has("skin_model_part_outer_initial_name"))){

// Create the breps for the outer sbm boundary
CreateBrepsSBMUtilities<Node, Point> CreateBrepsSBMUtilities(mEchoLevel);
CreateBrepsSBMUtilities.CreateSurrogateBoundary(mpSurface, r_model_part, A_uvw, B_uvw);

KRATOS_WARNING("None of the 'skin_model_part_name' have not been defined ") <<
"in the nurbs_geometry_modeler_sbm in the project paramer json" << std::endl;
return;
}

if (mParameters.Has("skin_model_part_name"))
skin_model_part_name = mParameters["skin_model_part_name"].GetString();
else
KRATOS_ERROR << "The skin_model_part name '" << skin_model_part_name << "' was not defined in the project parameters.\n" << std::endl;

// inner
ModelPart& skin_model_part_inner_initial = mpModel->HasModelPart(skin_model_part_inner_initial_name)
? mpModel->GetModelPart(skin_model_part_inner_initial_name)
: mpModel->CreateModelPart(skin_model_part_inner_initial_name);
// outer
ModelPart& skin_model_part_outer_initial = mpModel->HasModelPart(skin_model_part_outer_initial_name)
? mpModel->GetModelPart(skin_model_part_outer_initial_name)
: mpModel->CreateModelPart(skin_model_part_outer_initial_name);

// Create the surrogate sub model parts inner and outer
ModelPart& surrogate_sub_model_part_inner = iga_model_part.CreateSubModelPart("surrogate_inner");
ModelPart& surrogate_sub_model_part_outer = iga_model_part.CreateSubModelPart("surrogate_outer");

// Skin model part refined after Snake Process
ModelPart& skin_model_part = mpModel->CreateModelPart(skin_model_part_name);
skin_model_part.CreateSubModelPart("inner");
skin_model_part.CreateSubModelPart("outer");


// compute unique_knot_vector_u
Vector unique_knot_vector_u(2+(NumKnotSpansU-1));
unique_knot_vector_u[0] = mKnotVectorU[0]; unique_knot_vector_u[NumKnotSpansU] = mKnotVectorU[mKnotVectorU.size()-1];
for (SizeType i_knot_insertion = 0; i_knot_insertion < NumKnotSpansU-1; i_knot_insertion++) {
unique_knot_vector_u[i_knot_insertion+1] = mInsertKnotsU[i_knot_insertion];
}

// compute unique_knot_vector_v
Vector unique_knot_vector_v(2+(NumKnotSpansV-1));
unique_knot_vector_v[0] = mKnotVectorV[0]; unique_knot_vector_v[NumKnotSpansV] = mKnotVectorV[mKnotVectorV.size()-1];

for (SizeType i_knot_insertion = 0; i_knot_insertion < NumKnotSpansV-1; i_knot_insertion++) {
unique_knot_vector_v[i_knot_insertion+1] = mInsertKnotsV[i_knot_insertion];
}
SnakeSBMUtilities::CreateTheSnakeCoordinates(iga_model_part, skin_model_part_inner_initial, skin_model_part_outer_initial, skin_model_part, mEchoLevel,
unique_knot_vector_u, unique_knot_vector_v, mParameters) ;
// Create the breps for the outer sbm boundary
CreateBrepsSBMUtilities<Node, Point> CreateBrepsSBMUtilities(mEchoLevel);
CreateBrepsSBMUtilities.CreateSurrogateBoundary(mpSurface, r_model_part, surrogate_sub_model_part_inner, surrogate_sub_model_part_outer, A_uvw, B_uvw);
}

} // end namespace kratos
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// | / |
// ' / __| _` | __| _ \ __|
// . \ | ( | | ( |\__ `
// _|\_\_| \__,_|\__|\___/ ____/
// Multi-Physics
//
// License: BSD License
// Kratos default license: kratos/license.txt
//
// Main authors: Nicolo' Antonelli
// Andrea Gorgi
//

# pragma once

// System includes

// External includes

// Project includes
#include "nurbs_geometry_modeler.h"

namespace Kratos {

class KRATOS_API(IGA_APPLICATION) NurbsGeometryModelerSbm
: public NurbsGeometryModeler
{
public:
///@name Type Definitions
///@{
KRATOS_CLASS_POINTER_DEFINITION( NurbsGeometryModelerSbm );

using IndexType = std::size_t;
using SizeType = std::size_t;
using NodeType = Node;

using GeometryType = Geometry<NodeType>;
using GeometryPointerType = GeometryType::Pointer;

using NurbsSurfaceGeometryType = NurbsSurfaceGeometry<3, PointerVector<NodeType>>;
using NurbsSurfaceGeometryPointerType = NurbsSurfaceGeometryType::Pointer;

using NurbsVolumeGeometryType = NurbsVolumeGeometry<PointerVector<NodeType>>;
using NurbsVolumeGeometryPointerType = NurbsVolumeGeometryType::Pointer;

using ContainerNodeType = PointerVector<Node>;
using ContainerEmbeddedNodeType = PointerVector<Point>;

///@}
///@name Life Cycle
///@{

/// Default constructor.
NurbsGeometryModelerSbm()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

those defaults maybe they can be removed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm not wrong, the compiler will add it if not in there.

: NurbsGeometryModeler() {}

/// Constructor.
NurbsGeometryModelerSbm(
Model & rModel,
const Parameters ModelerParameters = Parameters())
: NurbsGeometryModeler(rModel, ModelerParameters)
, mpModel(&rModel)
{
}

/// Destructor.
~NurbsGeometryModelerSbm() = default;

/// Creates the Modeler Pointer
Modeler::Pointer Create(Model& rModel, const Parameters ModelParameters) const override
{
return Kratos::make_shared<NurbsGeometryModelerSbm>(rModel, ModelParameters);
}

///@}
///@name Stages
///@{

void SetupGeometryModel() override;

///@}

protected:

/**
* @brief Creates a regular grid composed out of bivariant B-splines.
* @param PointA Lower point of bounding box.
* @param PointB Upper point of bounding box.
* @param Order Polynomial degree in each direction u,v.
* @param NumKnotSpans Number of equidistant elements/knot spans in each direction u,v.
* @note The CP'S are defined as nodes and added to the rModelPart.
**/
void CreateAndAddRegularGrid2D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz, const Point& A_uvw, const Point& B_uvw,
SizeType OrderU, SizeType OrderV, SizeType NumKnotSpansU, SizeType NumKnotSpansV, bool add_surface_to_model_part ) override;

private:

///@name Private Member Variables
///@{

Model* mpModel;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, doesn't the base class already have a pointer to the Model?

You could just expose that through a protected member of the base class to avoid duplication/ambiguity.


///@}
///@name Private Operations
///@{

/**
* @brief Creates a cartesian grid composed out of trivariant B-spline cubes.
* @param PointA Lower point of bounding box.
* @param PointB Upper point of bounding box.
* @param Order Polynomial degree in each direction u,v,w.
* @param NumKnotSpans Number of equidistant elements/knot spans in each direction u,v,w.
* @note The CP'S are defined as nodes and added to the rModelPart.
**/
void CreateAndAddRegularGrid3D( ModelPart& r_model_part, const Point& A_xyz, const Point& B_xyz, const Point& A_uvw, const Point& B_uvw,
SizeType OrderU, SizeType OrderV, SizeType OrderW, SizeType NumKnotSpansU, SizeType NumKnotSpansV, SizeType NumKnotSpansW );

Parameters ReadParamatersFile(const std::string& rDataFileName) const;
};

} // End namesapce Kratos
Loading
Loading