1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| MyThread::results MyThread::solve(QVector<QVariant>& boundariesCdt, QVector<double>& forces)
{
results result; //Variable qui va contenir les résultats
//On copie la matrice de rigidité dans une autre matrice que l'on pourrat modifier
matCopy.setSize(mat.rowCount(),mat.columnCount());
for(int i=0;i<mat.rowCount();i++)
{
for(int j=0;j<mat.columnCount();j++)
{
matCopy(i,j) = mat(i,j);
}
}
//On copie les forces dans resultat.displacements (sera transformé par le pivot de gauss pour la résolution)
for(int j=0;j<forces.size();j++)
{
result.displacements.push_back(forces.at(j));
}
//Comme certaines réactions aux connecteurs sont inconnues mais on connait les déplacement, on ne peut pas appliquer le pivot de
//Gauss à certaines lignes. La seule solution est de la résoudre à part et d'appliquer le pivot aux lignes où le membre de droite
//est connu. Une fois qu'on aura calculé les déplacements, il suffira de résoudre les équations mises à part
//pour les efforts aux connecteurs.
for(int j=0;j<boundariesCdt.size();j++)
{
if(boundariesCdt.at(j)!=QVariant()) //Si le déplacement (ou la rotation) vaut une valeur, on modifie la matrice.
//Sinon on ne fait rien.
{
if(j<6) //Si on est dans les 6 premières lignes de la matrice (le noeud 1)
{
for(int i=0; i<matCopy.columnCount();i++)
{
if(i==j) //si i=j alors on incrit un 1, sinon un 0. Permet de faire une équation xi*1=0
{
matCopy(j,i) = 1;
}
else
{
matCopy(j,i) = 0;
}
}
result.displacements[j] = boundariesCdt[j].toDouble();
}
else //Si on est dans les 6 dernières lignes de la matrice (le dernier noeud)
{
for(int i=0; i<matCopy.columnCount();i++)
{
if(i==matCopy.rowCount()-12+j)//si i=n-12+j alors on incrit un 1, sinon un 0. Permet de faire une équation xi*1=0
{
matCopy(matCopy.rowCount()-12+j,i) = 1;
}
else
{
matCopy(matCopy.rowCount()-12+j,i) = 0;
}
}
result.displacements[result.displacements.size()-12+j] = boundariesCdt[j].toDouble();
}
}
}
//###############################################################################################################################
//Pivot de Gauss appliqué à "matCopy" et "result.displacement"
int r = 0;
int k = 0;
double maxPivot = 0;
for(double j=0; j<matCopy.columnCount();j++)
{
emit progressChanged(floor(100*j/(matCopy.columnCount()-1)));
maxPivot = 0; //On met "maxPivot" à une valeur minimale
//On cherche le coef max de la colonne j et on le stocke dans "maxPivot". L'indice de la ligne du pivot est k.
for(int i=r;i<matCopy.rowCount();i++)
{
if(matCopy(i,j)*matCopy(i,j)>maxPivot*maxPivot)
{
maxPivot = matCopy(i,j);
k = i;
}
}
if(matCopy(k,j)!=0)//Si le pivot est non nul, on procède aux opérations. Sinon, cela veut dire que toute la colonne est nulle
{
//############ On divise la ligne par le pivot (1 en début de ligne) ##############################
for(int i = 0; i<matCopy.columnCount();i++)
{
matCopy(k,i) /= maxPivot;
}
result.displacements[k] /= maxPivot;
double coef = 0;
//############ Echange des lignes r et k ##############################
for(int i = 0; i<matCopy.columnCount();i++)
{
coef = matCopy(k,i);
matCopy(k,i) = matCopy(r,i); //On modifie la ligne k
matCopy(r,i) = coef; //On modifie la ligne r
}
coef = forces[r];
result.displacements[r] = result.displacements[k];
result.displacements[k] = coef;
for(int i=0; i<matCopy.rowCount();i++)
{
if(i!=r)
{
double coefLigne = matCopy(i,j);
for(int l=0;l<matCopy.columnCount();l++)
{
matCopy(i,l) -= matCopy(r,l)*coefLigne; // [Li] = [Li] - [Lr]*coefLigne
}
result.displacements[i] -= result.displacements[r]*coefLigne;
}
}
r++;
}
}
//###############################################################################################################################
//Maintenant on va calculer les efforts aux connecteurs
for(int i=0;i<mat.rowCount();i++)
{
result.reactionLoads.push_back(0);
for(int j=0;j<mat.columnCount();j++)
{
result.reactionLoads[i] += mat(i,j)*result.displacements[j];
}
}
//"forces" est un tableau contenant toutes les solutions des déplacements
//"connectorReaction" est un tableau contenant toutes les solutions des efforts
return result;
} |
Partager