added subdomain support in Mesh class, CalculateLaplaceMult implementation

This commit is contained in:
jakob.schratter 2026-01-22 17:52:23 +01:00
commit 2e887c04bc
13 changed files with 4336 additions and 69057 deletions

View file

@ -383,6 +383,87 @@ void FEM_Matrix::Derive_Matrix_Pattern_slow()
return;
}
void FEM_Matrix::CalculateLaplaceMult(vector<double> &f)
{
cout << "\n############ FEM_Matrix::CalculateLaplaceMult ";
double tstart = omp_get_wtime(); // OpenMP
assert(_mesh.NdofsElement() == 3); // only for triangular, linear elements
//cout << _nnz << " vs. " << _id[_nrows] << " " << _nrows<< endl;
assert(_nnz == _id[_nrows]);
for (int k = 0; k < _nrows; ++k) {
_sk[k] = 0.0;
}
for (int k = 0; k < _nrows; ++k) {
f[k] = 0.0;
}
double ske[3][3], fe[3];
// Loop over all elements
auto const nelem = _mesh.Nelems();
auto const &ia = _mesh.GetConnectivity();
auto const &xc = _mesh.GetCoords();
const vector<int> sd_vec = _mesh.ElementSubdomains;
#pragma omp parallel for private(ske,fe)
for (int i = 0; i < nelem; ++i) {
auto subdomain = sd_vec[i];
double lambda = Thermal_coefficient(subdomain);
cout << subdomain << endl;
CalcElemSpecific(ia.data() + 3 * i, xc.data(), lambda, ske);
//AddElem(ia.data()+3 * i, ske, fe, _id.data(), _ik.data(), _sk.data(), f.data()); // GH: deprecated
AddElem_3(ia.data() + 3 * i, ske, fe, f);
}
double duration = omp_get_wtime() - tstart; // OpenMP
cout << "finished in " << duration << " sec. ########\n"; // ToDo: change to systemclock
//Debug();
return;
}
double FEM_Matrix::Thermal_coefficient(const int subdomain)
{
int matlab_sd_index = subdomain - 1;
double lambda = 0.0;
switch (matlab_sd_index)
{
// outside
case 0:
lambda = 1.0;
break;
// ceramic
case 1:
lambda = 1.0;
break;
// water
case 2:
lambda = 1.0;
break;
// air
case 3:
lambda = 1.0;
break;
default:
lambda = 1.0;
break;
}
return lambda;
}
void FEM_Matrix::CalculateLaplace(vector<double> &f)
{
@ -686,6 +767,26 @@ void CalcElem(int const ial[3], double const xc[], double ske[3][3], double fe[3
}
void CalcElemSpecific(int const ial[3], double const xc[], double const lambda, double ske[3][3])
{
const int i1 = 2 * ial[0], i2 = 2 * ial[1], i3 = 2 * ial[2];
const double x13 = xc[i3 + 0] - xc[i1 + 0], y13 = xc[i3 + 1] - xc[i1 + 1],
x21 = xc[i1 + 0] - xc[i2 + 0], y21 = xc[i1 + 1] - xc[i2 + 1],
x32 = xc[i2 + 0] - xc[i3 + 0], y32 = xc[i2 + 1] - xc[i3 + 1];
const double jac = fabs(x21 * y13 - x13 * y21);
ske[0][0] = lambda * 0.5 / jac * (y32 * y32 + x32 * x32);
ske[0][1] = lambda * 0.5 / jac * (y13 * y32 + x13 * x32);
ske[0][2] = lambda * 0.5 / jac * (y21 * y32 + x21 * x32);
ske[1][0] = ske[0][1];
ske[1][1] = lambda * 0.5 / jac * (y13 * y13 + x13 * x13);
ske[1][2] = lambda * 0.5 / jac * (y21 * y13 + x21 * x13);
ske[2][0] = ske[0][2];
ske[2][1] = ske[1][2];
ske[2][2] = lambda * 0.5 / jac * (y21 * y21 + x21 * x21);
}
void CalcElem_RHS(int const ial[3], double const xc[], double fe[3],
const std::function<double(double,double)> &func)
{