From dbc79ba992373cb58e62e65ecd184bc7348d7476 Mon Sep 17 00:00:00 2001 From: Klaus Boehnlein <klaus.boehnlein@tu-dresden.de> Date: Wed, 16 Jun 2021 00:48:40 +0200 Subject: [PATCH] corrected some errors --- src/dune-microstructure.cc | 359 +++++++++++++++++++++++++++++++++---- 1 file changed, 320 insertions(+), 39 deletions(-) diff --git a/src/dune-microstructure.cc b/src/dune-microstructure.cc index 187ae5a4..1c8835b5 100644 --- a/src/dune-microstructure.cc +++ b/src/dune-microstructure.cc @@ -50,6 +50,9 @@ #include <dune/microstructure/prestrainimp.hh> +#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh> + + using namespace Dune; @@ -392,6 +395,64 @@ void getOccupationPattern(const Basis& basis, MatrixIndexSet& nb) } } + + ////////////////////////////////////////////////////////////////// + // setIntegralZero: + int arbitraryIndex = 0; + + FieldVector<int,3> row; + unsigned int elementCounter = 1; + + for (const auto& element : elements(basis.gridView())) + { + localView.bind(element); + + if(elementCounter == 1) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet + { + for (int k = 0; k < 3; k++) + { + auto rowLocal = localView.tree().child(k).localIndex(arbitraryIndex); + row[k] = localView.index(rowLocal); + } + } + + // "global assembly" + for (int k = 0; k<3; k++) + for (size_t j=0; j<localView.size(); j++) + { + auto col = localView.index(j); + nb.add(row[k],col); + } + elementCounter++; + } + ///////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////// + // setOneBaseFunctionToZero necessary? + + //Determine 3 global indices (one for each component of an arbitrary FE-function).. oder mittels Offset? + // use first element: +// auto it = basis.gridView().template begin<0>(); +// localView.bind(*it); +// +// int arbitraryIndex = 0; +// FieldVector<int,3> row; //fill with Indices.. +// +// +// for (int k = 0; k < 3; k++) +// { +// auto rowLocal = localView.tree().child(k).localIndex(arbitraryIndex); +// row[k] = localView.index(rowLocal); +// auto cIt = stiffnessMatrix[row[k]].begin(); +// auto cEndIt = stiffnessMatrix[row[k]].end(); +// for (; cIt!=cEndIt; ++cIt) +// *cIt = (cIt.index()==row[k]) ? 1.0 : 0.0; +// } + + + + + } @@ -585,7 +646,7 @@ void assembleCellStiffness(const Basis& basis, const int localPhiOffset = localView.size(); - std::cout << "localPhiOffset : " << localPhiOffset << std::endl; +// std::cout << "localPhiOffset : " << localPhiOffset << std::endl; Dune::Matrix<double> elementMatrix; //eher das ?? // Dune::Matrix<FieldMatrix<double,1,1> > elementMatrix; @@ -653,7 +714,7 @@ void assembleCellLoad(const Basis& basis, std::cout << "assemble load vector." << std::endl; - b.resize(basis.size()); + b.resize(basis.size()+3); b = 0; auto localView = basis.localView(); @@ -709,6 +770,34 @@ void setOneBaseFunctionToZero(const Basis& basis, ) { + constexpr int dim = 3; + auto localView = basis.localView(); + + + + //Determine 3 global indices (one for each component of an arbitrary FE-function).. oder mittels Offset? + + // use first element: + auto it = basis.gridView().template begin<0>(); + localView.bind(*it); + + int arbitraryIndex = 0; + FieldVector<int,3> row; //fill with Indices.. + + for (int k = 0; k < dim; k++) + { + auto rowLocal = localView.tree().child(k).localIndex(arbitraryIndex); + row[k] = localView.index(rowLocal); + std::cout << "row[k]:" << row[k] << std::endl; + load_alpha1[row[k]] = 0.0; + load_alpha2[row[k]] = 0.0; + load_alpha3[row[k]] = 0.0; + auto cIt = stiffnessMatrix[row[k]].begin(); + auto cEndIt = stiffnessMatrix[row[k]].end(); + for (; cIt!=cEndIt; ++cIt) + *cIt = (cIt.index()==row[k]) ? 1.0 : 0.0; + } + } @@ -762,11 +851,11 @@ void setIntegralZero (const Basis& basis, { // if (elementCounter % 50 == 1) // std::cout << "integral = zero - treatment - element: " << elementCounter << std::endl; - +// std::cout << "element-number: " << elementCounter << std::endl; localView.bind(element); - if(elementCounter == 1) // get arbitraryIndex(global) for each Component + if(elementCounter == 1) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet { for (int k = 0; k < dim; k++) { @@ -805,29 +894,28 @@ void setIntegralZero (const Basis& basis, localFiniteElement.localBasis().evaluateFunction(quadPos, shapeFunctionValues); // Compute the shape function on the grid element - std::vector<FieldVector<double,1> > BasisFunctionValues(shapeFunctionValues.size()); - for (size_t i=0; i<BasisFunctionValues.size(); i++) - jacobian.mv(shapeFunctionValues[i], BasisFunctionValues[i]); +// std::vector<FieldVector<double,1> > BasisFunctionValues(shapeFunctionValues.size()); +// for (size_t i=0; i<BasisFunctionValues.size(); i++) +// jacobian.mv(shapeFunctionValues[i], BasisFunctionValues[i]); // no gradient! not needed! for (size_t i=0; i<localView.size(); i++) for (size_t k=0; k<nCompo; k++) { size_t idx = localView.tree().child(k).localIndex(i); - elementColumns[idx] += BasisFunctionValues[i] * quadPoint.weight() * integrationElement; // bei Periodicbasis einfach mit child(k) arbeiten... + elementColumns[idx] += shapeFunctionValues[i] * quadPoint.weight() * integrationElement; // bei Periodicbasis einfach mit child(k) arbeiten... +// elementColumns[idx] += BasisFunctionValues[i] * quadPoint.weight() * integrationElement; // bei Periodicbasis einfach mit child(k) arbeiten... } - - // "global assembly" for (int k = 0; k<dim; k++) for (size_t j=0; j<localView.size(); j++) { // auto colLocal = localView.tree().child(d).localIndex(j); auto col = localView.index(j); - stiffnessMatrix[row[k]][col] += elementColumns[j] * quadPoint.weight() * integrationElement; + stiffnessMatrix[row[k]][col] += elementColumns[j] * quadPoint.weight() * integrationElement; // TODO Müsste über eine LOOP ? } - elementCounter ++; + elementCounter++; }//end of quad }//end for each element @@ -838,6 +926,85 @@ void setIntegralZero (const Basis& basis, +template<class Basis, class LocalFunction> +double integralMean(const Basis& basis, + LocalFunction& fun + ) +{ + + using GridView = typename Basis::GridView; + using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; + + + constexpr int dim = 3; + using FuncScalar = std::function< FieldVector< double, dim>(const Domain&) >; + + auto localView = basis.localView(); + double r = 0.0; + double area = 0.0; + + // Compute area integral + for(const auto& element : elements(basis.gridView())) + { + + localView.bind(element); + const auto& localFiniteElement = localView.tree().child(0).finiteElement(); + int order = 2*(dim*localFiniteElement.localBasis().order()-1); + const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), order); + + for (const auto& quadPoint : quad) + { + const double integrationElement = element.geometry().integrationElement(quadPoint.position()); + area += quadPoint.weight() * integrationElement; + } + } + std::cout << "Domain-Area: " << area << std::endl; + + + for(const auto& element : elements(basis.gridView())) + { + + localView.bind(element); + fun.bind(element); + const auto& localFiniteElement = localView.tree().child(0).finiteElement(); + int order = 2*(dim*localFiniteElement.localBasis().order()-1); + const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), order); + + for (const auto& quadPoint : quad) + { + + const auto& quadPos = quadPoint.position(); + const double integrationElement = element.geometry().integrationElement(quadPos); + + +// std::vector<FieldMatrix<double,1,nCompo> > referenceGradients; +// localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients); +// +// std::vector< VectorRT > gradients(referenceGradients.size()); +// for (size_t i=0; i< gradients.size(); i++) +// jacobian.mv(referenceGradients[i][0], gradients[i]); + + auto value = fun(quadPos); +// auto value = localPhi_1(quadPos); +// auto value = FieldVector<double,dim>{1.0, 1.0, 1.0}; + + for(size_t k=0; k<3; k++) + r += value[k] * quadPoint.weight() * integrationElement; + + +// r += tmp * quadPoint.weight() * integrationElement; + + } + } + + + return r/area; + +} + + + + // ---- TODO - MatrixEmbedding function (iota) ---- ??? @@ -944,7 +1111,7 @@ int main(int argc, char *argv[]) FieldVector<double,dim> lower({0.0, 0.0, -1.0/2.0}); FieldVector<double,dim> upper({1.0, 1.0, 1.0/2.0}); - int nE = 1; + int nE = 3; std::array<int,dim> nElements={nE,nE,nE}; //#Elements in each direction @@ -954,7 +1121,7 @@ int main(int argc, char *argv[]) const GridView gridView_CE = grid_CE.leafGridView(); - + double areaDomain = 1.0; @@ -1026,11 +1193,13 @@ int main(int argc, char *argv[]) std::cout << "size feBasis: " << Basis_CE.size() << std::endl; std::cout << "basis.dimension()" << Basis_CE.dimension() <<std::endl; + const int phiOffset = Basis_CE.size(); + ///////////////////////////////////////////////////////// // Stiffness matrix and right hand side vector ///////////////////////////////////////////////////////// -// { linear_algebra_setup_begin } + // using VelocityVector = BlockVector<FieldVector<double,dim>>; // using PressureVector = BlockVector<double>; // using Vector = MultiTypeBlockVector<VelocityVector, PressureVector>; @@ -1041,7 +1210,7 @@ int main(int argc, char *argv[]) // using MatrixRow0 = MultiTypeBlockVector<Matrix00, Matrix01>; // using MatrixRow1 = MultiTypeBlockVector<Matrix10, Matrix11>; // using Matrix = MultiTypeBlockMatrix<MatrixRow0,MatrixRow1>; -// { linear_algebra_setup_end } + ///////////////////////////////////////////////////////// @@ -1079,18 +1248,18 @@ Func2Tensor x3G_3 = [] (const Domain& z) { - MatrixRT G_1 {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - MatrixRT G_2 {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0, 0.0, 0.0}}; - MatrixRT G_3 {{0.0, 0.5, 0.0}, {0.5, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - - printmatrix(std::cout, basisContainer[0] , "G_1", "--"); - printmatrix(std::cout, basisContainer[1] , "G_2", "--"); - printmatrix(std::cout, basisContainer[2] , "´G_3", "--"); - +MatrixRT G_1 {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; +MatrixRT G_2 {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0, 0.0, 0.0}}; +MatrixRT G_3 {{0.0, 0.5, 0.0}, {0.5, 0.0, 0.0}, {0.0, 0.0, 0.0}}; +std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; +// printmatrix(std::cout, basisContainer[0] , "G_1", "--"); +// printmatrix(std::cout, basisContainer[1] , "G_2", "--"); +// printmatrix(std::cout, basisContainer[2] , "´G_3", "--"); +// +// +// assembleCellStiffness(Basis_CE, muLocal, lambdaLocal, gamma, stiffnessMatrix_CE); @@ -1103,19 +1272,19 @@ printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix before B.C", "--"); // set Integral to zero -if(set_integral_zero) -{ - setIntegralZero(Basis_CE, stiffnessMatrix_CE, load_alpha1, load_alpha2, load_alpha3); - printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix after setIntegralZero", "--"); -} - +// if(set_integral_zero) +// { +// setIntegralZero(Basis_CE, stiffnessMatrix_CE, load_alpha1, load_alpha2, load_alpha3); +// printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix after setIntegralZero", "--"); +// } +// -// set Integral to zero +// set one basis-function to zero if(set_oneBasisFunction_Zero) { setOneBaseFunctionToZero(Basis_CE, stiffnessMatrix_CE, load_alpha1, load_alpha2, load_alpha3); - printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix after setIntegralZero", "--"); + printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix after setOneBasisFunctionToZero", "--"); } @@ -1123,6 +1292,12 @@ if(set_oneBasisFunction_Zero) + + + + + + // setzt gesamte Zeile = 0: // stiffnessMatrix_CE[2] = 0; // printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix MOD", "--"); @@ -1242,6 +1417,42 @@ solver.apply(x_3, load_alpha3, statistics); +// Extract phi_alpha & M_alpha coefficients +VectorCT phi_1, phi_2, phi_3; +phi_1.resize(Basis_CE.size()); +phi_1 = 0; +phi_2.resize(Basis_CE.size()); +phi_2 = 0; +phi_3.resize(Basis_CE.size()); +phi_3 = 0; + +// VectorCT m_1, m_2, m_3; +// m_1.resize(3); +// m_1 = 0; +// m_2.resize(3); +// m_2 = 0; +// m_3.resize(3); +// m_3 = 0; + +FieldVector<double,3> m_1, m_2, m_3; + + + +for(size_t i=0; i<Basis_CE.size();i++) +{ + phi_1[i] = x_1[i]; + phi_2[i] = x_2[i]; + phi_3[i] = x_3[i]; +} + +for(size_t i=0; i<3; i++) +{ + m_1[i] = x_1[phiOffset+i]; + m_2[i] = x_2[phiOffset+i]; + m_3[i] = x_3[phiOffset+i]; +} + + //////////////////////////////////////////////////////////////////////////// // Make a discrete function from the FE basis and the coefficient vector //////////////////////////////////////////////////////////////////////////// @@ -1249,18 +1460,88 @@ solver.apply(x_3, load_alpha3, statistics); using SolutionRange = FieldVector<double,dim>; // using SolutionRange = double; + +// auto correctorFunction_1 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( +// Basis_CE, +// Dune::Functions::HierarchicVectorWrapper<VectorCT, double>(phi_1)); // ?? + + + auto correctorFunction_1 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( Basis_CE, - x_1); + phi_1); + + +auto correctorFunction_2 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( + Basis_CE, + phi_2); + +auto correctorFunction_3 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( + Basis_CE, + phi_3); + + +// assemble M_alpha's (actually iota(M_alpha) ) + +MatrixRT M_1(0), M_2(0), M_3(0); + +for(size_t i=0; i<3; i++) +{ + M_1 += m_1[i]*basisContainer[i]; + M_2 += m_2[i]*basisContainer[i]; + M_3 += m_3[i]*basisContainer[i]; +} + + +printmatrix(std::cout, M_1, "Corrector-Matrix M_1", "--"); +printmatrix(std::cout, M_2, "Corrector-Matrix M_1", "--"); +printmatrix(std::cout, M_3, "Corrector-Matrix M_1", "--"); +auto localPhi_1 = localFunction(correctorFunction_1); + + + +double IM = 0.0; +IM = integralMean(Basis_CE, localPhi_1); +std::cout << "Integral-Mean: " << IM << std::endl; + +for(size_t i=0; i<Basis_CE.size();i++) +{ + phi_1[i] -= IM; // Müsste integralMean von jeder Komponente einzeln berechnen ??? +} + + +// INTEGRAL-MEAN TEST: +auto AVFunction_1 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( + Basis_CE, + phi_1); + +auto AVPhi_1 = localFunction(AVFunction_1); +double A = 0.0; +A = integralMean(Basis_CE, AVPhi_1); +std::cout << "Integral-Mean (TEST) : " << A << std::endl; + + + + +// FieldVector<double,3> ones = {1.0, 1.0, 1.0}; +// +// phi_1 - IM*; + + +// // const-function +// auto f1 = [](const auto& x) +// { +// return IM; // does not work.. +// }; +// +// +// VectorCT IM_1; +// interpolate(Basis_CE, IM_1, f1); - // use only first child of W_h to plot solution -// auto solutionFunction = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( -// Functions::subspaceBasis(dofMapWh, 0), -// x); ////////////////////////////////////////////////////////////////////////////////////////////// -- GitLab