Salome HOME
Check memory is initialized in output field functions
[tools/solverlab.git] / CoreFlows / Models / src / LinearElasticityModel.cxx
index 6bb90d34e2ffb56ebfdf3aef0ef67272e553a7a1..bdcd35c313ed2ea208d54dc2fe6e2c2313ccf594 100755 (executable)
@@ -89,6 +89,7 @@ LinearElasticityModel::LinearElasticityModel(int dim, bool FECalculation,  doubl
     _NdirichletNodes=0;
     _NunknownNodes=0;
     _dirichletValuesSet=false;   
+    _neumannValuesSet=false;   
     
     //Linear solver data
        _precision=1.e-6;
@@ -176,21 +177,21 @@ void LinearElasticityModel::initialize()
                 _runLogFile->close();
                 throw CdmathException("Missing boundary value");
             }
-            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType==NoTypeSpecified)
+            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType==NoneBCLinearElasticity)
             {
                 cout<<"!!! No boundary condition set for boundary node " << _boundaryNodeIds[i]<< endl;
                 *_runLogFile<< "!!!No boundary condition set for boundary node " << _boundaryNodeIds[i]<<endl;
                 _runLogFile->close();
                 throw CdmathException("Missing boundary condition");
             }
-            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType==Dirichlet)
+            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType==DirichletLinearElasticity)
                 _dirichletNodeIds.push_back(_boundaryNodeIds[i]);
-            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType!=Neumann)
+            else if(_limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType!=NeumannLinearElasticity)
             {
                 cout<<"!!! Wrong boundary condition "<< _limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType<< " set for boundary node " << _boundaryNodeIds[i]<< endl;
-                cout<<"!!! Accepted boundary conditions are Dirichlet "<< Dirichlet <<" and Neumann "<< Neumann << endl;
+                cout<<"!!! Accepted boundary conditions are Dirichlet "<< DirichletLinearElasticity <<" and Neumann "<< NeumannLinearElasticity << endl;
                 *_runLogFile<< "Wrong boundary condition "<< _limitField[_mesh.getNode(_boundaryNodeIds[i]).getGroupName()].bcType<< " set for boundary node " << _boundaryNodeIds[i]<<endl;
-                *_runLogFile<< "Accepted boundary conditions are Dirichlet "<< Dirichlet <<" and Neumann "<< Neumann <<endl;
+                *_runLogFile<< "Accepted boundary conditions are Dirichlet "<< DirichletLinearElasticity <<" and Neumann "<< NeumannLinearElasticity <<endl;
                 _runLogFile->close();
                 throw CdmathException("Wrong boundary condition");
             }
@@ -207,7 +208,7 @@ void LinearElasticityModel::initialize()
     else
         MatCreateSeqAIJ(PETSC_COMM_SELF, _NunknownNodes*_nVar, _NunknownNodes*_nVar, (1+_neibMaxNbNodes), PETSC_NULL, &_A);
 
-       VecCreate(PETSC_COMM_SELF, &_displacments);
+       VecCreate(PETSC_COMM_SELF, &_displacements);
 
        VecDuplicate(_displacements, &_b);//RHS of the linear system
 
@@ -219,11 +220,20 @@ void LinearElasticityModel::initialize()
        KSPGetPC(_ksp, &_pc);
        PCSetType(_pc, _pctype);
 
-    //Checking whether all boundaries are Neumann boundaries
-    map<string, LimitField>::iterator it = _limitField.begin();
-    while(it != _limitField.end() and (it->second).bcType == Neumann)
-        it++;
-    _onlyNeumannBC = (it == _limitField.end() && _limitField.size()>0);
+    //Checking whether all boundary conditions are Neumann boundary condition
+    if(!_neumannValuesSet)//Boundary conditions set via LimitField structure
+    {
+        map<string, LimitFieldLinearElasticity>::iterator it = _limitField.begin();
+        while(it != _limitField.end() and (it->second).bcType == NeumannLinearElasticity)
+            it++;
+        _onlyNeumannBC = (it == _limitField.end() && _limitField.size()>0);//what if _limitField.size()==0 ???
+    }
+    else
+        if(_FECalculation)
+            _onlyNeumannBC = _neumannBoundaryValues.size()==_NboundaryNodes;
+        else
+            _onlyNeumannBC = _neumannBoundaryValues.size()==_mesh.getBoundaryFaceIds().size();
+
     //If only Neumann BC, then matrix is singular and solution should be sought in space of mean zero vectors
     if(_onlyNeumannBC)
     {
@@ -269,14 +279,14 @@ Vector LinearElasticityModel::gradientNodal(Matrix M, vector< double > values){
        return result;    
 }
 
-double LinearElasticityModel::computeDiffusionMatrix(bool & stop)
+double LinearElasticityModel::computeStiffnessMatrix(bool & stop)
 {
     double result;
     
     if(_FECalculation)
-        result=computeDiffusionMatrixFE(stop);
+        result=computeStiffnessMatrixFE(stop);
     else
-        result=computeDiffusionMatrixFV(stop);
+        result=computeStiffnessMatrixFV(stop);
 
     if(_verbose or _system)
         MatView(_A,PETSC_VIEWER_STDOUT_SELF);
@@ -284,10 +294,10 @@ double LinearElasticityModel::computeDiffusionMatrix(bool & stop)
     return  result;
 }
 
-double LinearElasticityModel::computeDiffusionMatrixFE(bool & stop){
+double LinearElasticityModel::computeStiffnessMatrixFE(bool & stop){
        Cell Cj;
        string nameOfGroup;
-       double dn;
+       double dn, coeff;
        MatZeroEntries(_A);
        VecZeroEntries(_b);
     
@@ -345,7 +355,7 @@ double LinearElasticityModel::computeDiffusionMatrixFE(bool & stop){
                                 if( _dirichletValuesSet )//New way of storing BC
                                     valuesBorder[kdim]=_dirichletBoundaryValues[it->second];
                                 else    //old way of storing BC
-                                    valuesBorder[kdim]=_limitField[_mesh.getNode(nodeIds[kdim]).getGroupName()].Displacements;
+                                    valuesBorder[kdim]=_limitField[_mesh.getNode(nodeIds[kdim]).getGroupName()].displacement;
                             }
                             else
                                 valuesBorder[kdim]=Vector(_Ndim);                            
@@ -359,6 +369,29 @@ double LinearElasticityModel::computeDiffusionMatrixFE(bool & stop){
         }            
        }
     
+    //Calcul de la contribution de la condition limite de Neumann au second membre
+    if( _NdirichletNodes !=_NboundaryNodes)
+    {
+        vector< int > boundaryFaces = _mesh.getBoundaryFaceIds();
+        int NboundaryFaces=boundaryFaces.size();
+        for(int i = 0; i< NboundaryFaces ; i++)//On parcourt les faces du bord
+        {
+            Face Fi = _mesh.getFace(i);
+            for(int j = 0 ; j<_Ndim ; j++)//On parcourt les noeuds de la face
+            {
+                if(find(_dirichletNodeIds.begin(),_dirichletNodeIds.end(),Fi.getNodeId(j))==_dirichletNodeIds.end())//node j is an Neumann BC node (not a Dirichlet BC node)
+                {
+                    j_int=unknownNodeIndex(Fi.getNodeId(j), _dirichletNodeIds);//indice du noeud j en tant que noeud inconnu
+                    if( _neumannValuesSet )
+                        coeff =Fi.getMeasure()/(_Ndim+1)*_neumannBoundaryValues[Fi.getNodeId(j)];
+                    else    
+                        coeff =Fi.getMeasure()/(_Ndim+1)*_limitField[_mesh.getNode(Fi.getNodeId(j)).getGroupName()].normalForce;
+                    VecSetValue(_b, j_int, coeff, ADD_VALUES);
+                }
+            }
+        }
+    }
+
     MatAssemblyBegin(_A, MAT_FINAL_ASSEMBLY);
        MatAssemblyEnd(_A, MAT_FINAL_ASSEMBLY);
        VecAssemblyBegin(_b);
@@ -369,13 +402,13 @@ double LinearElasticityModel::computeDiffusionMatrixFE(bool & stop){
        return INFINITY;
 }
 
-double LinearElasticityModel::computeDiffusionMatrixFV(bool & stop){
+double LinearElasticityModel::computeStiffnessMatrixFV(bool & stop){
        long nbFaces = _mesh.getNumberOfFaces();
        Face Fj;
        Cell Cell1,Cell2;
        string nameOfGroup;
        double inv_dxi, inv_dxj;
-       double barycenterDistance;
+       double barycenterDistance,coeff;
        Vector normale(_Ndim);
        double dn;
        PetscInt idm, idn;
@@ -425,18 +458,23 @@ double LinearElasticityModel::computeDiffusionMatrixFV(bool & stop){
             {
                 nameOfGroup = Fj.getGroupName();
     
-                if (_limitField[nameOfGroup].bcType==Neumann){//Nothing to do
+                if (_limitField[nameOfGroup].bcType==NeumannLinearElasticity){
+                    if( _neumannValuesSet )
+                        coeff =Fi.getMeasure()*_neumannBoundaryValues[j];
+                    else    
+                        coeff =Fi.getMeasure()*_limitField[nameOfGroup].normalForce;
+                    VecSetValue(_b,idm,    coeff, ADD_VALUES);
                 }
-                else if(_limitField[nameOfGroup].bcType==Dirichlet){
+                else if(_limitField[nameOfGroup].bcType==DirichletLinearElasticity){
                     barycenterDistance=Cell1.getBarryCenter().distance(Fj.getBarryCenter());
                     MatSetValue(_A,idm,idm,dn*inv_dxi/barycenterDistance                           , ADD_VALUES);
-                    VecSetValue(_b,idm,    dn*inv_dxi/barycenterDistance*_limitField[nameOfGroup].T, ADD_VALUES);
+                    VecSetValue(_b,idm,    dn*inv_dxi/barycenterDistance*_limitField[nameOfGroup].displacement, ADD_VALUES);
                 }
                 else {
                     stop=true ;
-                    cout<<"!!!!!!!!!!!!!!! Error LinearElasticityModel::computeDiffusionMatrixFV !!!!!!!!!!"<<endl;
+                    cout<<"!!!!!!!!!!!!!!! Error LinearElasticityModel::computeStiffnessMatrixFV !!!!!!!!!!"<<endl;
                     cout<<"!!!!!! Boundary condition not accepted for boundary named !!!!!!!!!!"<<nameOfGroup<< ", _limitField[nameOfGroup].bcType= "<<_limitField[nameOfGroup].bcType<<endl;
-                    cout<<"Accepted boundary conditions are Neumann "<<Neumann<< " and Dirichlet "<<Dirichlet<<endl;
+                    cout<<"Accepted boundary conditions are Neumann "<<NeumannLinearElasticity<< " and Dirichlet "<<DirichletLinearElasticity<<endl;
                     *_runLogFile<<"!!!!!! Boundary condition not accepted for boundary named !!!!!!!!!!"<<nameOfGroup<< ", _limitField[nameOfGroup].bcType= "<<_limitField[nameOfGroup].bcType<<endl;
                     _runLogFile->close();
                     throw CdmathException("Boundary condition not accepted");
@@ -468,8 +506,8 @@ double LinearElasticityModel::computeDiffusionMatrixFV(bool & stop){
                }
                else
         {
-            *_runLogFile<<"LinearElasticityModel::computeDiffusionMatrixFV(): incompatible number of cells around a face"<<endl;
-                       throw CdmathException("LinearElasticityModel::computeDiffusionMatrixFV(): incompatible number of cells around a face");
+            *_runLogFile<<"LinearElasticityModel::computeStiffnessMatrixFV(): incompatible number of cells around a face"<<endl;
+                       throw CdmathException("LinearElasticityModel::computeStiffnessMatrixFV(): incompatible number of cells around a face");
         }
        }
 
@@ -531,7 +569,7 @@ bool LinearElasticityModel::solveLinearSystem()
 
     if(_conditionNumber)
         KSPSetComputeEigenvalues(_ksp,PETSC_TRUE);
-    KSPSolve(_ksp, _b, displacements);
+    KSPSolve(_ksp, _b, _displacements);
 
        KSPConvergedReason reason;
        KSPGetConvergedReason(_ksp,&reason);
@@ -690,7 +728,7 @@ bool LinearElasticityModel::solveStationaryProblem()
                *_runLogFile<< "Finite elements method"<< endl<<endl;
        }
 
-    computeDiffusionMatrix( stop);
+    computeStiffnessMatrix( stop);
     if (stop){
         cout << "Error : failed computing diffusion matrix, stopping calculation"<< endl;
         *_runLogFile << "Error : failed computing diffusion matrix, stopping calculation"<< endl;
@@ -806,6 +844,12 @@ LinearElasticityModel::setDirichletValues(map< int, double> dirichletBoundaryVal
     _dirichletValuesSet=true;
     _dirichletBoundaryValues=dirichletBoundaryValues;
 }
+void 
+LinearElasticityModel::setNeumannValues(map< int, double> neumannBoundaryValues)
+{
+    _neumannValuesSet=true;
+    _neumannBoundaryValues=neumannBoundaryValues;
+}
 
 double 
 LinearElasticityModel::getConditionNumber(bool isSingular, double tol) const