Kratos: 'Vector of matrices' type Kratos variable

Created on 5 Apr 2017  Â·  23Comments  Â·  Source: KratosMultiphysics/Kratos

Hi All,

I’m looking to output the top and bottom surface stresses of each layer in a composite shell element. Does anyone know of a way to define a Kratos variable which is a vector of matrices? I tried the following, which didn't work:

KRATOS_CREATE_VARIABLE(std::vector<Matrix>, SHELL_ORTHOTROPIC_LAYER_STRESSES)

Any help would be much appreciated!

Discussion Help Wanted

All 23 comments

Try to use a typedef:

typedef std::vector<Matrix> MatrixArrayType

and then:

KRATOS_CREATE_VARIABLE(MatrixArrayType, SHELL_ORTHOTROPIC_LAYER_STRESSES)

@MassimoPetracca

hi massimo, could you comment on how you were doing output for multiple layers?

Thanks for the suggestion @loumalouomega, but it still throws the same error:

image

Which is that file variable.h?

I created a branch and I will commit now. The problem was that the Variable class can not "print" the info (Stream) if the variable is a vector, then the trick is to consider a pointer to that type:

KRATOS_DEFINE_VARIABLE( MatrixArrayType*, SHELL_ORTHOTROPIC_LAYER_STRESSES )

The thing is that you will need to consider as a pointer all the time, this means example:

~c
MatrixArrayType* pLayerStresses = pElem->GetValue(SHELL_ORTHOTROPIC_LAYER_STRESSES);
for ( unsigned int i_layer = 0; i_layer < pLayerStresses->size(); ++i_layer )
{
Matrix = (*pLayerStresses)[i_layer];
}
~

Wouldn't it be better to add the print function for this type of variables? Using a (raw!) pointer creates all kinds of trouble with memory management, since you have to allocate and free the memory yourself.

That would be nice, this is trick that I have been using with the contact containers (that used to be std::vectors and now are std::unordered_map), @roigcarlo show me this trick and I wasn't aware of the evil side of the raw pointers

@pooyan-dadvand maybe can contribute to this issue

@jcotela I am going to try using a make_shared, that way it will be a shared pointer

If the problem is the print function I agree that is better to just add it. The problem with shared pointers is that you wont be able to register it as a kratos variable ( Honestly I am not very sure about this ).

If I recall correctly, I suggested the raw pointer because there was not a easy way to use unordered sets as kratos variables

@roigcarlo I am having problems with the make_shared, both with std::make_shared and boost::make_shared, trying to make it work

@roigcarlo It is with boost::shared_ptr not with make_shared

Ok, looks that it compiles, I will change this in my ContactStructuralApplication too, thanks @jcotela . By the way @peterjwilson the example will be:

~c
auto pLayerStresses = pElem->GetValue(SHELL_ORTHOTROPIC_LAYER_STRESSES); // NOTE: I use auto to avoid declare the type everytime
for ( unsigned int i_layer = 0; i_layer < pLayerStresses->size(); ++i_layer )
{
Matrix = (*pLayerStresses)[i_layer];
}
~

Thanks heaps for your help @loumalouomega! Apologies from this Kratos rookie, but where should I add the above code?

Wherever you want to use the variable, is just an example. Don't worry I am still very rookie compared with most the main Kratos developers

I completely disagree with the use of raw pointer there because it can easy lead to memory leak unless you carefully delete what you allocate. And if somebody wants to use it in a node as a historical variable it will cause a mess in clone time step. (it will copy the pointer pointing to the old data)

An easy solution would be to define the ostream operator << for std::vector<Matrix> as suggested by @jcotela.

However in my opinion instead of using a combination of vector and matrix, it would be better to have a class:

class ShellMultiLayerStresses{
    std::vector<Matrix> mLayerStresses;
public:
     Matrix const& GetLayerStress(std::size_t LayerIndex);
     void SetLayerStress(std::size_t LayerIndex, Matrix& NewLayerStress);
};

+1 for Pooyan s suggestion

El 6 abr. 2017 3:11 p. m., "Pooyan Dadvand" notifications@github.com
escribió:

I completely disagree with the use of raw pointer there because it can
easy lead to memory leak unless you carefully delete what you allocate. And
if somebody wants to use it in a node as a historical variable it will
cause a mess in clone time step. (it will copy the pointer pointing to the
old data)

An easy solution would be to define the ostream operator << for
std::vector as suggested by @jcotela https://github.com/jcotela.

However in my opinion instead of using a combination of vector and matrix,
it would be better to have a class:

class ShellMultiLayerStresses{
std::vector mLayerStresses;
public:
Matrix const& GetLayerStress(std::size_t LayerIndex);
void SetLayerStress(std::size_t LayerIndex, Matrix& NewLayerStress);
};

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/KratosMultiphysics/Kratos/issues/252#issuecomment-292169518,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AHr7EbT0d5_HBloJhNVqMWgukph1wwUvks5rtOR8gaJpZM4M0Ux_
.

Thanks @pooyan-dadvand , I will change the raw pointers I defined in my application to avoid these undesired problems

If you know that these matrices will be always of the same size (2x2 or 3x3) maybe is better to make matrices bounded ?

(if it will be always the size 3x3):

class ShellMultiLayerStresses{
private:
    std::vector<bounded_matrix<double,3,3> > mLayerStresses;
public:
     bounded_matrix<double,3,3> const& GetLayerStress(std::size_t LayerIndex) {...};
     void SetLayerStress(std::size_t LayerIndex, bounded_matrix<double,3,3>& NewLayerStress){ ... };
};

Thanks @josep-m-carbonell, indeed it is an important improvement!

@peterjwilson Did we solved this issue?

Yep, closing this.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

loumalouomega picture loumalouomega  Â·  5Comments

armingeiser picture armingeiser  Â·  6Comments

e-dub picture e-dub  Â·  3Comments

Gaoliu19910601 picture Gaoliu19910601  Â·  6Comments

roigcarlo picture roigcarlo  Â·  7Comments