diff --git a/HowTo-DefineMaterial.txt b/HowTo-DefineMaterial.txt deleted file mode 100644 index e243669c510c7a1125eb25d38dd5b7bc6084fab2..0000000000000000000000000000000000000000 --- a/HowTo-DefineMaterial.txt +++ /dev/null @@ -1,7 +0,0 @@ - - -1. Define new material, prestrain and indicator function @ /dune/microstructure/materialDefinitions.hh - -2. Add Case (Materialname) to "setupMaterial" method @ /dune/prestrainedMaterial.hh - -3. set new materialname parameter @ /inputs/cellsolver.parset diff --git a/dune-sequential.opts b/dune-sequential.opts index 6b5af3f7e50c500d39ac1cb6d598c95cbd163f2e..3f0e2266bee47ff0e62f14e4378cad3a56ad445b 100755 --- a/dune-sequential.opts +++ b/dune-sequential.opts @@ -1,2 +1,2 @@ # set flags for CMake: -CMAKE_FLAGS="-DCMAKE_CXX_FLAGS='-g -fdiagnostics-color=always -Wall -fmax-errors=2 -DHAVE_CSTDDEF' -DCMAKE_DISABLE_FIND_PACKAGE_MPI=TRUE -DUG_ENABLE_PARALLEL=false -DCMAKE_BUILD_TYPE=Debug" +CMAKE_FLAGS="-DCMAKE_CXX_FLAGS='-g -fdiagnostics-color=always -Wall -fmax-errors=2 -DHAVE_CSTDDEF' -DCMAKE_DISABLE_FIND_PACKAGE_MPI=TRUE -DUG_ENABLE_PARALLEL=false -DCMAKE_BUILD_TYPE=Release" \ No newline at end of file diff --git a/install-commands.sh b/install-commands.sh deleted file mode 100644 index 4838b4a5e13c5d6604c63ce438b002a0a33aeb15..0000000000000000000000000000000000000000 --- a/install-commands.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - - - - -git clone https://gitlab.dune-project.org/core/dune-common -git clone https://gitlab.dune-project.org/core/dune-geometry -git clone https://gitlab.dune-project.org/core/dune-grid -git clone https://gitlab.dune-project.org/core/dune-istl -git clone https://gitlab.dune-project.org/core/dune-localfunctions.git -git clone https://gitlab.dune-project.org/staging/dune-functions -git clone https://gitlab.dune-project.org/staging/dune-uggrid -git clone https://gitlab.dune-project.org/staging/dune-typetree -git clone git@gitlab.mn.tu-dresden.de:s7603593/dune-microstructure.git - -git clone https://git.imp.fu-berlin.de/agnumpde/dune-matrix-vector.git -git clone https://git.imp.fu-berlin.de/agnumpde/dune-fufem.git -git clone https://git.imp.fu-berlin.de/agnumpde/dune-solvers.git - - - -dunecontrol all - -./dune-microstructure/build-cmake/src/Cell-Problem ./dune-microstructure/inputs/cellsolver.parset diff --git a/install-commands_release.sh b/install-commands_release.sh new file mode 100755 index 0000000000000000000000000000000000000000..6778c365fbacb8579090d75740b831c93f635b1e --- /dev/null +++ b/install-commands_release.sh @@ -0,0 +1,19 @@ +#!/bin/sh +git clone https://gitlab.dune-project.org/core/dune-common --branch releases/2.9 +git clone https://gitlab.dune-project.org/core/dune-geometry --branch releases/2.9 +git clone https://gitlab.dune-project.org/core/dune-grid --branch releases/2.9 +git clone https://gitlab.dune-project.org/core/dune-istl --branch releases/2.9 +git clone https://gitlab.dune-project.org/core/dune-localfunctions.git --branch releases/2.9 +git clone https://gitlab.dune-project.org/staging/dune-functions --branch releases/2.9 +git clone https://gitlab.dune-project.org/staging/dune-uggrid --branch releases/2.9 +git clone https://gitlab.dune-project.org/staging/dune-typetree --branch releases/2.9 +git clone https://gitlab.dune-project.org/fufem/dune-fufem.git --branch releases/2.9 +git clone https://git.imp.fu-berlin.de/agnumpde/dune-matrix-vector.git --branch releases/2.9 +git clone https://git.imp.fu-berlin.de/agnumpde/dune-solvers.git --branch releases/2.9 +#git clone git@gitlab.mn.tu-dresden.de:ag-sander/dune/dune-elasticity.git --branch releases/2.9 +git clone git@gitlab.mn.tu-dresden.de:osander/dune-gfe.git +git clone https://gitlab.mn.tu-dresden.de/iwr/dune-gmsh4.git +git clone https://gitlab.mn.tu-dresden.de/s7603593/dune-microstructure.git + +# to build run: +# dunecontrol --opts=dune-sequential.opts all diff --git a/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem-New.cc b/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem-New.cc deleted file mode 100644 index 22fe2eaf1c788753a83a9618d7f7cf7cc368adbf..0000000000000000000000000000000000000000 --- a/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem-New.cc +++ /dev/null @@ -1,798 +0,0 @@ -#include <config.h> -#include <array> -#include <vector> -#include <fstream> - -#include <iostream> -#include <dune/common/indices.hh> -#include <dune/common/bitsetvector.hh> -#include <dune/common/parametertree.hh> -#include <dune/common/parametertreeparser.hh> -#include <dune/common/float_cmp.hh> -#include <dune/common/math.hh> - - -#include <dune/geometry/quadraturerules.hh> - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -// #include <dune/grid/utility/structuredgridfactory.hh> //TEST -#include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh> - -#include <dune/istl/matrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/multitypeblockmatrix.hh> -#include <dune/istl/multitypeblockvector.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/istl/solvers.hh> -#include <dune/istl/spqr.hh> -#include <dune/istl/preconditioners.hh> -#include <dune/istl/io.hh> - -#include <dune/functions/functionspacebases/interpolate.hh> -#include <dune/functions/backends/istlvectorbackend.hh> -#include <dune/functions/functionspacebases/powerbasis.hh> -#include <dune/functions/functionspacebases/compositebasis.hh> -#include <dune/functions/functionspacebases/lagrangebasis.hh> -#include <dune/functions/functionspacebases/periodicbasis.hh> -#include <dune/functions/functionspacebases/subspacebasis.hh> -#include <dune/functions/functionspacebases/boundarydofs.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> -#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh> - -#include <dune/common/fvector.hh> -#include <dune/common/fmatrix.hh> - -#include <dune/microstructure/prestrain_material_geometry.hh> -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/vtk_filler.hh> //TEST -#include <dune/microstructure/CorrectorComputer.hh> -#include <dune/microstructure/EffectiveQuantitiesComputer.hh> -#include <dune/microstructure/prestrainedMaterial.hh> - -#include <dune/solvers/solvers/umfpacksolver.hh> //TEST -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number - -// #include <dune/fufem/discretizationerror.hh> -#include <dune/fufem/dunepython.hh> -#include <python2.7/Python.h> - -#include <dune/fufem/functions/virtualgridfunction.hh> //TEST - -// #include <boost/multiprecision/cpp_dec_float.hpp> -#include <any> -#include <variant> -#include <string> -#include <iomanip> // needed when working with relative paths e.g. from python-scripts - -using namespace Dune; -using namespace MatrixOperations; - -////////////////////////////////////////////////////////////////////// -// Helper functions for Table-Output -////////////////////////////////////////////////////////////////////// -/*! Center-aligns string within a field of width w. Pads with blank spaces - to enforce alignment. */ -std::string center(const std::string s, const int w) { - std::stringstream ss, spaces; - int padding = w - s.size(); // count excess room to pad - for(int i=0; i<padding/2; ++i) - spaces << " "; - ss << spaces.str() << s << spaces.str(); // format with padding - if(padding>0 && padding%2!=0) // if odd #, add 1 space - ss << " "; - return ss.str(); -} - -/* Convert double to string with specified number of places after the decimal - and left padding. */ -template<class type> -std::string prd(const type x, const int decDigits, const int width) { - std::stringstream ss; -// ss << std::fixed << std::right; - ss << std::scientific << std::right; // Use scientific Output! - ss.fill(' '); // fill space around displayed # - ss.width(width); // set width around displayed # - ss.precision(decDigits); // set # places after decimal - ss << x; - return ss.str(); -} - -////////////////////////////////////////////////// -// Infrastructure for handling periodicity -////////////////////////////////////////////////// -// Check whether two points are equal on R/Z x R/Z x R -auto equivalent = [](const FieldVector<double,3>& x, const FieldVector<double,3>& y) - { - return ( (FloatCmp::eq(x[0],y[0]) or FloatCmp::eq(x[0]+1,y[0]) or FloatCmp::eq(x[0]-1,y[0])) - and (FloatCmp::eq(x[1],y[1]) or FloatCmp::eq(x[1]+1,y[1]) or FloatCmp::eq(x[1]-1,y[1])) - and (FloatCmp::eq(x[2],y[2])) - ); - }; - - - -// // a function: -// int half(int x, int y) {return x/2+y/2;} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int main(int argc, char *argv[]) -{ - MPIHelper::instance(argc, argv); - - Dune::Timer globalTimer; - - ParameterTree parameterSet; - if (argc < 2) - ParameterTreeParser::readINITree("../../inputs/cellsolver.parset", parameterSet); - else - { - ParameterTreeParser::readINITree(argv[1], parameterSet); - ParameterTreeParser::readOptions(argc, argv, parameterSet); - } - - //--- Output setter - std::string outputPath = parameterSet.get("outputPath", "../../outputs"); - - //--- setup Log-File - std::fstream log; - log.open(outputPath + "/output.txt" ,std::ios::out); - - std::cout << "outputPath:" << outputPath << std::endl; - -// parameterSet.report(log); // short Alternativ - - //--- Get Path for Material/Geometry functions - std::string geometryFunctionPath = parameterSet.get<std::string>("geometryFunctionPath"); - //--- Start Python interpreter - Python::start(); - Python::Reference main = Python::import("__main__"); - Python::run("import math"); - Python::runStream() - << std::endl << "import sys" - << std::endl << "sys.path.append('" << geometryFunctionPath << "')" - << std::endl; - - - constexpr int dim = 3; - constexpr int dimWorld = 3; - - // Debug/Print Options - bool print_debug = parameterSet.get<bool>("print_debug", false); - - // VTK-write options - bool write_materialFunctions = parameterSet.get<bool>("write_materialFunctions", false); - bool write_prestrainFunctions = parameterSet.get<bool>("write_prestrainFunctions", false); - - - - - /////////////////////////////////// - // Get Parameters/Data - /////////////////////////////////// - double gamma = parameterSet.get<double>("gamma",1.0); // ratio dimension reduction to homogenization - double alpha = parameterSet.get<double>("alpha", 2.0); - double theta = parameterSet.get<double>("theta",1.0/4.0); - /////////////////////////////////// - // Get Material Parameters - /////////////////////////////////// - std::string imp = parameterSet.get<std::string>("material_prestrain_imp", "analytical_Example"); - log << "material_prestrain used: "<< imp << std::endl; - double beta = parameterSet.get<double>("beta",2.0); - double mu1 = parameterSet.get<double>("mu1",1.0);; - double mu2 = beta*mu1; - double lambda1 = parameterSet.get<double>("lambda1",0.0);; - double lambda2 = beta*lambda1; - - - if(imp == "material_neukamm") - { - std::cout <<"mu: " << parameterSet.get<std::array<double,3>>("mu", {1.0,3.0,2.0}) << std::endl; - std::cout <<"lambda: " << parameterSet.get<std::array<double,3>>("lambda", {1.0,3.0,2.0}) << std::endl; - } - else - { - std::cout <<"mu: " << parameterSet.get<double>("mu1",1.0) << std::endl; - std::cout <<"lambda: " << parameterSet.get<double>("lambda1",0.0) << std::endl; - } - - /////////////////////////////////// - // Get Prestrain/Parameters - /////////////////////////////////// - auto prestrainImp = PrestrainImp<dim>(); - auto B_Term = prestrainImp.getPrestrain(parameterSet); - - - - log << "----- Input Parameters -----: " << std::endl; - log << "alpha: " << alpha << std::endl; - log << "gamma: " << gamma << std::endl; - log << "theta: " << theta << std::endl; - log << "beta: " << beta << std::endl; - log << "material parameters: " << std::endl; - log << "mu1: " << mu1 << "\nmu2: " << mu2 << std::endl; - log << "lambda1: " << lambda1 <<"\nlambda2: " << lambda2 << std::endl; - log << "----------------------------: " << std::endl; - - /////////////////////////////////// - // Generate the grid - /////////////////////////////////// - // --- Corrector Problem Domain (-1/2,1/2)^3: - FieldVector<double,dim> lower({-1.0/2.0, -1.0/2.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0/2.0, 1.0/2.0, 1.0/2.0}); - - std::array<int,2> numLevels = parameterSet.get<std::array<int,2>>("numLevels", {1,3}); - int levelCounter = 0; - - - /////////////////////////////////// - // Create Data Storage - /////////////////////////////////// - //--- Storage:: #1 level #2 L2SymError #3 L2SymErrorOrder #4 L2Norm(sym) #5 L2Norm(sym-analytic) #6 L2Norm(phi_1) - std::vector<std::variant<std::string, size_t , double>> Storage_Error; - //--- Storage:: | level | q1 | q2 | q3 | q12 | q23 | b1 | b2 | b3 | - std::vector<std::variant<std::string, size_t , double>> Storage_Quantities; - - // for(const size_t &level : numLevels) // explixite Angabe der levels.. {2,4} - for(size_t level = numLevels[0] ; level <= numLevels[1]; level++) // levels von bis.. [2,4] - { - std::cout << " ----------------------------------" << std::endl; - std::cout << "GridLevel: " << level << std::endl; - std::cout << " ----------------------------------" << std::endl; - - Storage_Error.push_back(level); - Storage_Quantities.push_back(level); - std::array<int, dim> nElements = {(int)std::pow(2,level) ,(int)std::pow(2,level) ,(int)std::pow(2,level)}; - std::cout << "Number of Grid-Elements in each direction: " << nElements << std::endl; - log << "Number of Grid-Elements in each direction: " << nElements << std::endl; - - using CellGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; - CellGridType grid_CE(lower,upper,nElements); - using GridView = CellGridType::LeafGridView; - const GridView gridView_CE = grid_CE.leafGridView(); - if(print_debug) - std::cout << "Host grid has " << gridView_CE.size(dim) << " vertices." << std::endl; - - // //not needed - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - using Domain = GridView::Codim<0>::Geometry::GlobalCoordinate; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - // using Func2Tensor = std::function< MatrixRT(const Domain&) >; - // using VectorCT = BlockVector<FieldVector<double,1> >; - // using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - - /////////////////////////////////// - // Create Lambda-Functions for material Parameters depending on microstructure - /////////////////////////////////// - auto materialImp = IsotropicMaterialImp<dim>(); - auto muTerm = materialImp.getMu(parameterSet); - auto lambdaTerm = materialImp.getLambda(parameterSet); - - auto muGridF = Dune::Functions::makeGridViewFunction(muTerm, gridView_CE); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambdaTerm, gridView_CE); - auto lambdaLocal = localFunction(lambdaGridF); - - - //--- Choose a finite element space for Cell Problem - using namespace Functions::BasisFactory; - Functions::BasisFactory::Experimental::PeriodicIndexSet periodicIndices; - - //--- get PeriodicIndices for periodicBasis (Don't do the following in real life: It has quadratic run-time in the number of vertices.) - for (const auto& v1 : vertices(gridView_CE)) - for (const auto& v2 : vertices(gridView_CE)) - if (equivalent(v1.geometry().corner(0), v2.geometry().corner(0))) - { - periodicIndices.unifyIndexPair({gridView_CE.indexSet().index(v1)}, {gridView_CE.indexSet().index(v2)}); - } - - //--- setup first order periodic Lagrange-Basis - auto Basis_CE = makeBasis( - gridView_CE, - power<dim>( // eig dimworld?!?! - Functions::BasisFactory::Experimental::periodic(lagrange<1>(), periodicIndices), - flatLexicographic() - //blockedInterleaved() // Not Implemented - )); - if(print_debug) - std::cout << "power<periodic> basis has " << Basis_CE.dimension() << " degrees of freedom" << std::endl; - - - - - - //TEST - //Read from Parset... - // int Phases = parameterSet.get<int>("Phases", 3); - - - // std::string materialFunctionName = parameterSet.get<std::string>("materialFunction", "material"); - // Python::Module module = Python::import(materialFunctionName); - - - - // auto indicatorFunction = Python::make_function<double>(module.get("f")); - // Func2Tensor indicatorFunction = Python::make_function<double>(module.get("f")); - // auto materialFunction_ = Python::make_function<double>(module.get("f")); - // auto materialFunction_ = Python::make_function<double>(module.get("f")); - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - - // int Phases; - // module.get("Phases").toC<int>(Phases); - // std::cout << "Number of Phases used:" << Phases << std::endl; - - - // std::cout << typeid(mu_).name() << '\n'; - - - //---- Get mu/lambda values (for isotropic material) from Material-file - // FieldVector<double,3> mu_(0); - // module.get("mu_").toC<FieldVector<double,3>>(mu_); - // printvector(std::cout, mu_ , "mu_", "--"); - // FieldVector<double,3> lambda_(0); - // module.get("lambda_").toC<FieldVector<double,3>>(lambda_); - // printvector(std::cout, lambda_ , "lambda_", "--"); - - - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // TESTING PRESTRAINEDMATERIAL.HH: - using Func2TensorParam = std::function< MatrixRT(const MatrixRT& ,const Domain&) >; - - auto material_ = prestrainedMaterial(gridView_CE,parameterSet); - // Func2Tensor elasticityTensor = material_.getElasticityTensor(); - // auto elasticityTensor = material_.getElasticityTensor(); - // Func2TensorParam elasticityTensor_ = *material_.getElasticityTensor(); - auto elasticityTensor_ = material_.getElasticityTensor(); - - // Func2TensorParam TestTensor = Python::make_function<MatrixRT>(module.get("H")); - - // std::cout << "decltype(elasticityTensor_) " << decltype(elasticityTensor_) << std::endl; - - - // std::cout << "typeid(elasticityTensor).name() :" << typeid(elasticityTensor_).name() << '\n'; - // std::cout << "typeid(TestTensor).name() :" << typeid(TestTensor).name() << '\n'; - - using MatrixFunc = std::function< MatrixRT(const MatrixRT&) >; - // std::cout << "Import NOW:" << std::endl; - // MatrixFunc symTest = Python::make_function<MatrixRT>(module.get("sym")); - // auto indicatorFunction = Python::make_function<double>(module.get("indicatorFunction")); - - //localize.. - // auto indicatorFunctionGVF = Dune::Functions::makeGridViewFunction(indicatorFunction , Basis_CE.gridView()); - // GridViewFunction<double(const Domain&), GridView> indicatorFunctionGVF = Dune::Functions::makeGridViewFunction(indicatorFunction , Basis_CE.gridView()); - // auto localindicatorFunction = localFunction(indicatorFunctionGVF); - - - // auto indicatorFunctionGVF = material_.getIndicatorFunction(); - // auto localindicatorFunction = localFunction(indicatorFunctionGVF); - - auto localindicatorFunction = material_.getIndicatorFunction(); - - // GridView::Element - // auto localindicatorFunction = localFunction(indicatorFunction); - - // std::cout << "typeid(localindicatorFunction).name() :" << typeid(localindicatorFunction).name() << '\n'; - - // using MatrixDomainFunc = std::function< MatrixRT(const MatrixRT&,const Domain&)>; - // // MatrixFunc elasticityTensor = Python::make_function<MatrixRT>(module.get("L")); - - // auto elasticityTensorGVF = Dune::Functions::makeGridViewFunction(elasticityTensor , Basis_CE.gridView()); - // auto localElasticityTensor = localFunction(elasticityTensorGVF); - - // Func2Tensor forceTerm = [] (const Domain& x) { - // return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - // }; - - // auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, Basis_CE.gridView()); - // auto loadFunctional = localFunction(loadGVF); - - MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - // auto xu = symTest(G1_); - // std::cout << "TEST NOW:" << std::endl; - // printmatrix(std::cout, symTest(G1_), "symTest(G1_)", "--"); - - // auto TestTensorGVF = Dune::Functions::makeGridViewFunction(TestTensor , Basis_CE.gridView()); - // auto localTestTensor = localFunction(TestTensorGVF ); - - - // printmatrix(std::cout, elasticityTensor(G1_), "elasticityTensor(G1_)", "--"); - // auto temp = elasticityTensor(G1_); - - - - // for (const auto& element : elements(Basis_CE.gridView())) - // { - // localindicatorFunction.bind(element); - // int orderQR = 2; - // const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - // for (const auto& quadPoint : quad) - // { - // const auto& quadPos = quadPoint.position(); - - // // std::cout << "localindicatorFunction(quadPos): " << localindicatorFunction(quadPos) << std::endl; - - - - // // std::cout << "quadPos : " << quadPos << std::endl; - // // auto temp = TestTensor(G1_, element.geometry().global(quadPos)); - // // auto temp2 = elasticityTensor_(G1_, element.geometry().global(quadPos)); - // // std::cout << "material_.applyElasticityTensor:" << std::endl; - // // auto tmp3 = material_.applyElasticityTensor(G1_, element.geometry().global(quadPos)); - // // auto tmp3 = material_.applyElasticityTensor(G1_, quadPos); - // // printmatrix(std::cout, tmp3, "tmp3", "--"); - // } - // } - - - - // for (auto&& vertex : vertices(gridView_CE)) - // { - // std::cout << "vertex.geometry().corner(0):" << vertex.geometry().corner(0)<< std::endl; - // auto tmp = vertex.geometry().corner(0); - // auto temp = elasticityTensor(tmp); - // // std::cout << "materialFunction_(vertex.geometry().corner(0))", materialFunction_(vertex.geometry().corner(0)) << std::endl; - // // printmatrix(std::cout, localElasticityTensor(G1_,tmp), "localElasticityTensor(vertex.geometry().corner(0))", "--"); - // } - - - - // std::function<int(int,int)> fn1 = half; - // std::cout << "fn1(60,20): " << fn1(60,20) << '\n'; - - - // std::cout << typeid(elasticityTensorGVF).name() << '\n'; - // std::cout << typeid(localElasticityTensor).name() << '\n'; - - - // ParameterTree parameterSet_2; - // ParameterTreeParser::readINITree(geometryFunctionPath + "/"+ materialFunctionName + ".py", parameterSet_2); - - // auto lu = parameterSet_2.get<FieldVector<double,3>>("lu", {1.0,3.0,2.0}); - // std::cout <<"lu[1]: " << lu[1]<< std::endl; - // std::cout <<"lu: " << parameterSet_2.get<std::array<double,3>>("lu", {1.0,3.0,2.0}) << std::endl; - - // auto mU_ = module.evaluate(parameterSet_2.get<std::string>("lu", "[1,2,3]")); - // std::cout << "typeid(mU_).name()" << typeid(mU_.operator()()).name() << '\n'; - - - // for (auto&& vertex : vertices(gridView_CE)) - // { - // std::cout << "vertex.geometry().corner(0):" << vertex.geometry().corner(0)<< std::endl; - // // std::cout << "materialFunction_(vertex.geometry().corner(0))", materialFunction_(vertex.geometry().corner(0)) << std::endl; - // printvector(std::cout, materialFunction_(vertex.geometry().corner(0)), "materialFunction_(vertex.geometry().corner(0))", "--"); - // } - // std::cout << "materialFunction_({0.0,0.0,0.0})", materialFunction_({0.0,0.0,0.0}) << std::endl; - - - - // -------------------------------------------------------------- - - //TODO// Phasen anhand von Mu bestimmen? - //TODO: DUNE_THROW(Exception, "Inconsistent choice of interpolation method"); if number of Phases != mu/lambda parameters - - //FÜR L GARNICHT NÖTIG DENN RÜCKGABETYPE IS IMMER MATRIXRT!?!: - // BEi materialfunction (isotopic) reicht auch FieldVector<double,2> für lambda/mu - - // switch (Phases) - // { - // case 1: //homogeneous material - // { - // std::cout << "Phase - 1" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // case 2: - // { - // std::cout << "Phase - 1" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // case 3: - // { - // std::cout << "Phase - 3" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // } - - - // switch (Phases) - // { - // case 1: //homogeneous material - // { - // std::cout << "Phases - 1" << std::endl; - // std::array<double,1> mu_ = parameterSet.get<std::array<double,1>>("mu", {1.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_] (const Domain& x) {return mu_;}; - // break; - // } - // case 2: - // { - // std::cout << "Phases - 2" << std::endl; - // std::array<double,2> mu_ = parameterSet.get<std::array<double,2>>("mu", {1.0,3.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_,indicatorFunction] (const Domain& x) - // { - // if (indicatorFunction(x) == 1) - // return mu_[0]; - // else - // return mu_[1]; - // }; - // break; - // } - // case 3: - // { - // std::cout << "Phases - 3" << std::endl; - // std::array<double,3> mu_ = parameterSet.get<std::array<double,3>>("mu", {1.0,3.0, 5.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_,indicatorFunction] (const Domain& x) - // { - // if (indicatorFunction(x) == 1) - // return mu_[0]; - // else if (indicatorFunction(x) == 2) - // return mu_[1]; - // else - // return mu_[2]; - // }; - // break; - // } - // } - - - - - //TEST -// std::cout << "Test crossSectionDirectionScaling:" << std::endl; -/* - MatrixRT T {{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}; - printmatrix(std::cout, T, "Matrix T", "--"); - - auto ST = crossSectionDirectionScaling((1.0/5.0),T); - printmatrix(std::cout, ST, "scaled Matrix T", "--");*/ - - //TEST -// auto QuadraticForm = [] (const double mu, const double lambda, const MatrixRT& M) { -// -// return lambda*std::pow(trace(M),2) + 2*mu*pow(norm(sym(M)),2); -// }; - - - - - //------------------------------------------------------------------------------------------------ - //--- compute Correctors - // auto correctorComputer = CorrectorComputer(Basis_CE, muTerm, lambdaTerm, gamma, log, parameterSet); - auto correctorComputer = CorrectorComputer(Basis_CE, material_, muTerm, lambdaTerm, gamma, log, parameterSet); - correctorComputer.solve(); - - - -////////////////////////////////////////////////// - - - //--- check Correctors (options): - if(parameterSet.get<bool>("write_L2Error", false)) - correctorComputer.computeNorms(); - if(parameterSet.get<bool>("write_VTK", false)) - correctorComputer.writeCorrectorsVTK(level); - //--- additional Test: check orthogonality (75) from paper: - if(parameterSet.get<bool>("write_checkOrthogonality", false)) - correctorComputer.check_Orthogonality(); - //--- Check symmetry of stiffness matrix - if(print_debug) - correctorComputer.checkSymmetry(); - - // auto B_Term = material_.getPrestrainFunction(); - - - //--- compute effective quantities - auto effectiveQuantitiesComputer = EffectiveQuantitiesComputer(correctorComputer,B_Term,material_); - effectiveQuantitiesComputer.computeEffectiveQuantities(); - - - - - //--- Test:: Compute Qeff without using the orthogonality (75)... - // only really makes a difference whenever the orthogonality is not satisfied! - // std::cout << "----------computeFullQ-----------"<< std::endl; //TEST - // effectiveQuantitiesComputer.computeFullQ(); - - //--- get effective quantities - auto Qeff = effectiveQuantitiesComputer.getQeff(); - auto Beff = effectiveQuantitiesComputer.getBeff(); - printmatrix(std::cout, Qeff, "Matrix Qeff", "--"); - printvector(std::cout, Beff, "Beff", "--"); - - //--- write effective quantities to matlab folder (for symbolic minimization) - if(parameterSet.get<bool>("write_toMATLAB", false)) - effectiveQuantitiesComputer.writeToMatlab(outputPath); - - std::cout.precision(10); - std::cout<< "q1 : " << Qeff[0][0] << std::endl; - std::cout<< "q2 : " << Qeff[1][1] << std::endl; - std::cout<< "q3 : " << std::fixed << Qeff[2][2] << std::endl; - std::cout<< std::fixed << std::setprecision(6) << "q_onetwo=" << Qeff[0][1] << std::endl; - // ------------------------------------------- - - - //TEST - // Func2Tensor x3G_1 = [] (const Domain& x) { - // return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - // }; - - // double energy = effectiveQuantitiesComputer.energySP(x3G_1,x3G_1); - // std::cout << "energy:" << energy << std::endl; - - Storage_Quantities.push_back(Qeff[0][0] ); - Storage_Quantities.push_back(Qeff[1][1] ); - Storage_Quantities.push_back(Qeff[2][2] ); - Storage_Quantities.push_back(Qeff[0][1] ); - Storage_Quantities.push_back(Qeff[1][2] ); - Storage_Quantities.push_back(Beff[0]); - Storage_Quantities.push_back(Beff[1]); - Storage_Quantities.push_back(Beff[2]); - - log << "size of FiniteElementBasis: " << Basis_CE.size() << std::endl; - log << "q1=" << Qeff[0][0] << std::endl; - log << "q2=" << Qeff[1][1] << std::endl; - log << "q3=" << Qeff[2][2] << std::endl; - log << "q12=" << Qeff[0][1] << std::endl; - log << "q23=" << Qeff[1][2] << std::endl; - log << std::fixed << std::setprecision(6) << "q_onetwo=" << Qeff[0][1] << std::endl; - log << "b1=" << Beff[0] << std::endl; - log << "b2=" << Beff[1] << std::endl; - log << "b3=" << Beff[2] << std::endl; - log << "mu_gamma=" << Qeff[2][2] << std::endl; // added for Python-Script - - - - - if (write_materialFunctions) - { - using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); - VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); - - using GridViewVTK = VTKGridType::LeafGridView; - const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - - auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); - auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - - std::vector<double> mu_CoeffP0; - Functions::interpolate(scalarP0FeBasis, mu_CoeffP0, muTerm); - auto mu_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, mu_CoeffP0); - - std::vector<double> mu_CoeffP1; - Functions::interpolate(scalarP1FeBasis, mu_CoeffP1, muTerm); - auto mu_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, mu_CoeffP1); - - - std::vector<double> lambda_CoeffP0; - Functions::interpolate(scalarP0FeBasis, lambda_CoeffP0, lambdaTerm); - auto lambda_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, lambda_CoeffP0); - - std::vector<double> lambda_CoeffP1; - Functions::interpolate(scalarP1FeBasis, lambda_CoeffP1, lambdaTerm); - auto lambda_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, lambda_CoeffP1); - - VTKWriter<GridView> MaterialVtkWriter(gridView_VTK); - - MaterialVtkWriter.addVertexData( - mu_DGBF_P1, - VTK::FieldInfo("mu_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - mu_DGBF_P0, - VTK::FieldInfo("mu_P0", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addVertexData( - lambda_DGBF_P1, - VTK::FieldInfo("lambda_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - lambda_DGBF_P0, - VTK::FieldInfo("lambda_P0", VTK::FieldInfo::Type::scalar, 1)); - - MaterialVtkWriter.write(outputPath + "/MaterialFunctions-level"+ std::to_string(level) ); - std::cout << "wrote data to file:" + outputPath +"/MaterialFunctions-level" + std::to_string(level) << std::endl; - - } - - -// if (write_prestrainFunctions) -// { -// using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// // VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// // VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); -// using GridViewVTK = VTKGridType::LeafGridView; -// const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - -// FTKfillerContainer<dim> VTKFiller; -// VTKFiller.vtkPrestrainNorm(gridView_VTK, B_Term, "PrestrainBNorm"); - -// // WORKS Too -// VTKFiller.vtkProblemCell(gridView_VTK, B_Term, muLocal,"VTKProblemCell");; - - -// // TEST -// auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); -// auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - -// std::vector<double> B_CoeffP0; -// Functions::interpolate(scalarP0FeBasis, B_CoeffP0, B_Term); -// auto B_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, B_CoeffP0); - - - -// VTKWriter<GridView> PrestrainVtkWriter(gridView_VTK); - -// PrestrainVtkWriter.addCellData( -// B_DGBF_P0, -// VTK::FieldInfo("B_P0", VTK::FieldInfo::Type::scalar, 1)); - -// PrestrainVtkWriter.write(outputPath + "/PrestrainFunctions-level"+ std::to_string(level) ); -// std::cout << "wrote data to file:" + outputPath +"/PrestrainFunctions-level" + std::to_string(level) << std::endl; - -// } - - - - - levelCounter++; - } // Level-Loop End - - - - - ////////////////////////////////////////// - //--- Print Storage - int tableWidth = 12; - std::cout << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("q12",tableWidth) << " | " - << center("q23",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - std::cout << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("q12",tableWidth) << " | " - << center("q23",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - - int StorageCount2 = 0; - for(auto& v: Storage_Quantities) - { - std::visit([tableWidth](auto&& arg){std::cout << center(prd(arg,5,1),tableWidth) << " | ";}, v); - std::visit([tableWidth, &log](auto&& arg){log << center(prd(arg,5,1),tableWidth) << " & ";}, v); - StorageCount2++; - if(StorageCount2 % 9 == 0 ) - { - std::cout << std::endl; - log << std::endl; - } - } - std::cout << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - - log.close(); - - std::cout << "Total time elapsed: " << globalTimer.elapsed() << std::endl; - - - -} diff --git a/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem.cc b/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem.cc deleted file mode 100644 index 682244ca658f50a2f5766735179b42ed66bc5ee5..0000000000000000000000000000000000000000 --- a/src/deprecated_code/30-8-22_TestingFiles-Comments/Cell-Problem.cc +++ /dev/null @@ -1,2726 +0,0 @@ -#include <config.h> -#include <array> -#include <vector> -#include <fstream> - -#include <iostream> -#include <dune/common/indices.hh> -#include <dune/common/bitsetvector.hh> -#include <dune/common/parametertree.hh> -#include <dune/common/parametertreeparser.hh> -#include <dune/common/float_cmp.hh> -#include <dune/common/math.hh> - - - -#include <dune/geometry/quadraturerules.hh> - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -#include <dune/grid/utility/structuredgridfactory.hh> //TEST - -#include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh> - -#include <dune/istl/matrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/multitypeblockmatrix.hh> -#include <dune/istl/multitypeblockvector.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/istl/solvers.hh> -#include <dune/istl/spqr.hh> -#include <dune/istl/preconditioners.hh> -#include <dune/istl/io.hh> - -#include <dune/functions/functionspacebases/interpolate.hh> - -#include <dune/functions/backends/istlvectorbackend.hh> -#include <dune/functions/functionspacebases/powerbasis.hh> -#include <dune/functions/functionspacebases/compositebasis.hh> - -#include <dune/functions/functionspacebases/lagrangebasis.hh> -#include <dune/functions/functionspacebases/periodicbasis.hh> - -#include <dune/functions/functionspacebases/subspacebasis.hh> -#include <dune/functions/functionspacebases/boundarydofs.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> - -#include <dune/common/fvector.hh> -#include <dune/common/fmatrix.hh> - -#include <dune/microstructure/prestrain_material_geometry.hh> -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/vtk_filler.hh> //TEST - -#include <dune/solvers/solvers/umfpacksolver.hh> //TEST - - -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number - -#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh> - -#include <dune/fufem/dunepython.hh> -#include <python2.7/Python.h> - -// #include <dune/fufem/discretizationerror.hh> -// #include <boost/multiprecision/cpp_dec_float.hpp> -// #include <boost/any.hpp> - -#include <any> -#include <variant> -#include <string> -#include <iomanip> // needed when working with relative paths e.g. from python-scripts - -using namespace Dune; -using namespace MatrixOperations; - - -////////////////////////////////////////////////////////////////////// -// Helper functions for Table-Output -////////////////////////////////////////////////////////////////////// -/*! Center-aligns string within a field of width w. Pads with blank spaces - to enforce alignment. */ -std::string center(const std::string s, const int w) { - std::stringstream ss, spaces; - int padding = w - s.size(); // count excess room to pad - for(int i=0; i<padding/2; ++i) - spaces << " "; - ss << spaces.str() << s << spaces.str(); // format with padding - if(padding>0 && padding%2!=0) // if odd #, add 1 space - ss << " "; - return ss.str(); -} - -/* Convert double to string with specified number of places after the decimal - and left padding. */ -template<class type> -std::string prd(const type x, const int decDigits, const int width) { - std::stringstream ss; -// ss << std::fixed << std::right; - ss << std::scientific << std::right; // Use scientific Output! - ss.fill(' '); // fill space around displayed # - ss.width(width); // set width around displayed # - ss.precision(decDigits); // set # places after decimal - ss << x; - return ss.str(); -} - - - - -template<class Basis, class Matrix> -void checkSymmetry(const Basis& basis, - Matrix& matrix - ) -{ - std::cout << "--- Check Symmetry ---" << std::endl; - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - - const int localPhiOffset = localView.size(); - - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - if(abs( matrix[row][col] - matrix[col][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - for (size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - if(abs( matrix[row][phiOffset+m] - matrix[phiOffset+m][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - - } - for (size_t m=0; m<3; m++ ) - for (size_t n=0; n<3; n++ ) - { - if(abs( matrix[phiOffset+m][phiOffset+n] - matrix[phiOffset+n][phiOffset+m]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - - } - std::cout << "--- Symmetry test passed ---" << std::endl; -} - - - - -template<class Basis> -auto arbitraryComponentwiseIndices(const Basis& basis, - const int elementNumber, - const int leafIdx - ) -{ - // (Local Approach -- works for non Lagrangian-Basis too) - // Input : elementNumber & localIdx - // Output : determine all Component-Indices that correspond to that basis-function - auto localView = basis.localView(); - - FieldVector<int,3> row; - int elementCounter = 0; - - for (const auto& element : elements(basis.gridView())) - { - if(elementCounter == elementNumber) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet - { - localView.bind(element); - - for (int k = 0; k < 3; k++) - { - auto rowLocal = localView.tree().child(k).localIndex(leafIdx); //Input: LeafIndex! TODO bräuchte hier (Inverse ) Local-to-Leaf Idx Map - row[k] = localView.index(rowLocal); - // std::cout << "rowLocal:" << rowLocal << std::endl; - // std::cout << "row[k]:" << row[k] << std::endl; - } - } - elementCounter++; - } - return row; -} - - - - -template<class LocalView, class Matrix, class localFunction1, class localFunction2> -void computeElementStiffnessMatrix(const LocalView& localView, - Matrix& elementMatrix, - const localFunction1& mu, - const localFunction2& lambda, - const double gamma - ) -{ - // Local StiffnessMatrix of the form: - // | phi*phi m*phi | - // | phi *m m*m | - using Element = typename LocalView::Element; - const Element element = localView.element(); - auto geometry = element.geometry(); - constexpr int dim = Element::dimension; - constexpr int dimWorld = dim; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - elementMatrix.setSize(localView.size()+3, localView.size()+3); //extend by dim ´R_sym^{2x2} - elementMatrix = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); -// std::cout << "localView.size(): " << localView.size() << std::endl; -// std::cout << "nSf : " << nSf << std::endl; - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} // wird nicht als Funktion benötigt da konstant... - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - -// double elementContribution = 0.0; - -// std::cout << "Print QuadratureOrder:" << orderQR << std::endl; //TEST` - - int QPcounter= 0; - for (const auto& quadPoint : quad) - { - QPcounter++; - const auto& quadPos = quadPoint.position(); - const auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(quadPos); - const auto integrationElement = geometry.integrationElement(quadPos); - - std::vector< FieldMatrix< double, 1, dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, - referenceGradients); - // Compute the shape function gradients on the grid element - std::vector<FieldVector<double,dim> > gradients(referenceGradients.size()); - - for (size_t i=0; i<gradients.size(); i++) - jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]); - - for (size_t l=0; l< dimWorld; l++) - for (size_t j=0; j < nSf; j++ ) - { - size_t row = localView.tree().child(l).localIndex(j); - // (scaled) Deformation gradient of the test basis function - MatrixRT defGradientV(0); - defGradientV[l][0] = gradients[j][0]; // Y - defGradientV[l][1] = gradients[j][1]; //X2 -// defGradientV[l][2] = (1.0/gamma)*gradients[j][2]; //X3 - defGradientV[l][2] = gradients[j][2]; //X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma),defGradientV); - // "phi*phi"-part - for (size_t k=0; k < dimWorld; k++) - for (size_t i=0; i < nSf; i++) - { - // (scaled) Deformation gradient of the ansatz basis function - MatrixRT defGradientU(0); - defGradientU[k][0] = gradients[i][0]; // Y - defGradientU[k][1] = gradients[i][1]; //X2 -// defGradientU[k][2] = (1.0/gamma)*gradients[i][2]; //X3 - defGradientU[k][2] = gradients[i][2]; //X3 - // printmatrix(std::cout, defGradientU , "defGradientU", "--"); - defGradientU = crossSectionDirectionScaling((1.0/gamma),defGradientU); - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); -// double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), defGradientU, defGradientV); //TEST -// double energyDensity = generalizedDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); // also works.. - - size_t col = localView.tree().child(k).localIndex(i); - - elementMatrix[row][col] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "m*phi" & "phi*m" - part - for( size_t m=0; m<3; m++) - { - double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV); -// double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], defGradientV); //TEST - auto value = energyDensityGphi * quadPoint.weight() * integrationElement; - elementMatrix[row][localPhiOffset+m] += value; - elementMatrix[localPhiOffset+m][row] += value; - } - - } - // "m*m"-part - for(size_t m=0; m<3; m++) //TODO ist symmetric.. reicht die hälfte zu berechnen!!! - for(size_t n=0; n<3; n++) - { - -// std::cout << "QPcounter: " << QPcounter << std::endl; -// std::cout << "m= " << m << " n = " << n << std::endl; -// printmatrix(std::cout, basisContainer[m] , "basisContainer[m]", "--"); -// printmatrix(std::cout, basisContainer[n] , "basisContainer[n]", "--"); -// std::cout << "integrationElement:" << integrationElement << std::endl; -// std::cout << "quadPoint.weight(): "<< quadPoint.weight() << std::endl; -// std::cout << "mu(quadPos): " << mu(quadPos) << std::endl; -// std::cout << "lambda(quadPos): " << lambda(quadPos) << std::endl; - - - double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n]); -// double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], basisContainer[n]); //TEST - elementMatrix[localPhiOffset+m][localPhiOffset+n] += energyDensityGG * quadPoint.weight() * integrationElement; // += !!!!! (Fixed-Bug) - -// std::cout << "energyDensityGG:" << energyDensityGG<< std::endl; -// std::cout << "product " << energyDensityGG * quadPoint.weight() * integrationElement << std::endl; -// printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); - - } - } - -// std::cout << "Number of QuadPoints:" << QPcounter << std::endl; -// printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); -} - - - -// Get the occupation pattern of the stiffness matrix -template<class Basis, class ParameterSet> -void getOccupationPattern(const Basis& basis, MatrixIndexSet& nb, ParameterSet& parameterSet) -{ - // OccupationPattern: - // | phi*phi m*phi | - // | phi *m m*m | - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - nb.resize(basis.size()+3, basis.size()+3); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - for (size_t i=0; i<localView.size(); i++) - { - // The global index of the i-th vertex of the element - auto row = localView.index(i); - for (size_t j=0; j<localView.size(); j++ ) - { - // The global index of the j-th vertex of the element - auto col = localView.index(j); - nb.add(row[0],col[0]); // nun würde auch nb.add(row,col) gehen.. - } - } - for (size_t i=0; i<localView.size(); i++) - { - auto row = localView.index(i); - - for (size_t j=0; j<3; j++ ) - { - nb.add(row,phiOffset+j); // m*phi part of StiffnessMatrix - nb.add(phiOffset+j,row); // phi*m part of StiffnessMatrix - } - } - for (size_t i=0; i<3; i++ ) - for (size_t j=0; j<3; j++ ) - { - nb.add(phiOffset+i,phiOffset+j); // m*m part of StiffnessMatrix - } - } - ////////////////////////////////////////////////////////////////// - // setOneBaseFunctionToZero - ////////////////////////////////////////////////////////////////// - if(parameterSet.template get<bool>("set_oneBasisFunction_Zero ", true)){ - FieldVector<int,3> row; - unsigned int arbitraryLeafIndex = parameterSet.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet.template get<unsigned int>("arbitraryElementNumber", 0); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); // macht keinen Unterschied ob hier k oder 0.. - const auto nSf = localFiniteElement.localBasis().size(); - assert(arbitraryLeafIndex < nSf ); - assert(arbitraryElementNumber < basis.gridView().size(0)); // "arbitraryElementNumber larger than total Number of Elements" - - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - row = arbitraryComponentwiseIndices(basis,arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<3; k++) - nb.add(row[k],row[k]); - } -} - - - -// Compute the source term for a single element -// < L (sym[D_gamma*nabla phi_i] + M_i ), x_3G_alpha > -template<class LocalView, class LocalFunction1, class LocalFunction2, class Vector, class LocalForce> -void computeElementLoadVector( const LocalView& localView, - LocalFunction1& mu, - LocalFunction2& lambda, - const double gamma, - Vector& elementRhs, - const LocalForce& forceTerm - ) -{ - // | f*phi| - // | --- | - // | f*m | - using Element = typename LocalView::Element; - const auto element = localView.element(); - const auto geometry = element.geometry(); - constexpr int dim = Element::dimension; - constexpr int dimWorld = dim; - - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - // Set of shape functions for a single element - const auto& localFiniteElement= localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - elementRhs.resize(localView.size() +3); - elementRhs = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); -// std::cout << "Quad-Rule order used: " << orderQR << std::endl; - - for (const auto& quadPoint : quad) - { - const FieldVector<double,dim>& quadPos = quadPoint.position(); - const auto jacobian = geometry.jacobianInverseTransposed(quadPos); - const double integrationElement = geometry.integrationElement(quadPos); - - std::vector<FieldMatrix<double,1,dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients); - - std::vector< FieldVector< double, dim> > gradients(referenceGradients.size()); - for (size_t i=0; i< gradients.size(); i++) - jacobian.mv(referenceGradients[i][0], gradients[i]); - - //TEST -// std::cout << "forceTerm(element.geometry().global(quadPos)):" << std::endl; -// std::cout << forceTerm(element.geometry().global(quadPos)) << std::endl; -// std::cout << "forceTerm(quadPos)" << std::endl; -// std::cout << forceTerm(quadPos) << std::endl; -// -// //TEST QUadrature -// std::cout << "quadPos:" << quadPos << std::endl; -// std::cout << "element.geometry().global(quadPos):" << element.geometry().global(quadPos) << std::endl; -// // // -// // // -// std::cout << "quadPoint.weight() :" << quadPoint.weight() << std::endl; -// std::cout << "integrationElement(quadPos):" << integrationElement << std::endl; -// std::cout << "mu(quadPos) :" << mu(quadPos) << std::endl; -// std::cout << "lambda(quadPos) :" << lambda(quadPos) << std::endl; - - - // "f*phi"-part - for (size_t i=0; i < nSf; i++) - for (size_t k=0; k < dimWorld; k++) - { - // Deformation gradient of the ansatz basis function - MatrixRT defGradientV(0); - defGradientV[k][0] = gradients[i][0]; // Y - defGradientV[k][1] = gradients[i][1]; // X2 -// defGradientV[k][2] = (1.0/gamma)*gradients[i][2]; // - defGradientV[k][2] = gradients[i][2]; // X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma),defGradientV); - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),forceTerm(quadPos), defGradientV ); -// double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)),forceTerm(quadPos), defGradientV ); //TEST -// double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),(-1.0)*forceTerm(quadPos), defGradientV ); //TEST -// double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),forceTerm(element.geometry().global(quadPos)), defGradientV ); //TEST - - size_t row = localView.tree().child(k).localIndex(i); - elementRhs[row] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "f*m"-part - for (size_t m=0; m<3; m++) - { - double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), forceTerm(quadPos),basisContainer[m] ); -// double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), forceTerm(quadPos),basisContainer[m] ); //TEST -// double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), (-1.0)*forceTerm(quadPos),basisContainer[m] ); //TEST -// double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), forceTerm(element.geometry().global(quadPos)),basisContainer[m] );//TEST - elementRhs[localPhiOffset+m] += energyDensityfG * quadPoint.weight() * integrationElement; -// std::cout << "energyDensityfG * quadPoint.weight() * integrationElement: " << energyDensityfG * quadPoint.weight() * integrationElement << std::endl; - } - } -} - - - -template<class Basis, class Matrix, class LocalFunction1, class LocalFunction2, class ParameterSet> -void assembleCellStiffness(const Basis& basis, - LocalFunction1& muLocal, - LocalFunction2& lambdaLocal, - const double gamma, - Matrix& matrix, - ParameterSet& parameterSet - ) -{ - std::cout << "assemble Stiffness-Matrix begins." << std::endl; - - MatrixIndexSet occupationPattern; - getOccupationPattern(basis, occupationPattern, parameterSet); - occupationPattern.exportIdx(matrix); - matrix = 0; - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - const int localPhiOffset = localView.size(); -// Dune::Timer Time; - //std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - Dune::Matrix<FieldMatrix<double,1,1> > elementMatrix; - computeElementStiffnessMatrix(localView, elementMatrix, muLocal, lambdaLocal, gamma); - -// std::cout << "local assembly time:" << Time.elapsed() << std::endl; - - //printmatrix(std::cout, elementMatrix, "ElementMatrix", "--"); - //std::cout << "elementMatrix.N() : " << elementMatrix.N() << std::endl; - //std::cout << "elementMatrix.M() : " << elementMatrix.M() << std::endl; - - //TEST - //Check Element-Stiffness-Symmetry: - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - if(abs( elementMatrix[i][j] - elementMatrix[j][i]) > 1e-12 ) - std::cout << "ELEMENT-STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL STIFFNES ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - matrix[row][col] += elementMatrix[i][j]; - } - for (size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - matrix[row][phiOffset+m] += elementMatrix[i][localPhiOffset+m]; - matrix[phiOffset+m][row] += elementMatrix[localPhiOffset+m][i]; - } - for (size_t m=0; m<3; m++ ) - for (size_t n=0; n<3; n++ ) - matrix[phiOffset+m][phiOffset+n] += elementMatrix[localPhiOffset+m][localPhiOffset+n]; - - // printmatrix(std::cout, matrix, "StiffnessMatrix", "--"); - } -} - - -template<class Basis, class LocalFunction1, class LocalFunction2, class Vector, class Force> -void assembleCellLoad(const Basis& basis, - LocalFunction1& muLocal, - LocalFunction2& lambdaLocal, - const double gamma, - Vector& b, - const Force& forceTerm - ) -{ - // std::cout << "assemble load vector." << std::endl; - b.resize(basis.size()+3); - b = 0; - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - // Transform G_alpha's to GridViewFunctions/LocalFunctions - auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, basis.gridView()); - auto loadFunctional = localFunction(loadGVF); - -// int counter = 1; - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - loadFunctional.bind(element); - - const int localPhiOffset = localView.size(); - // std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - - BlockVector<FieldVector<double,1> > elementRhs; -// std::cout << "----------------------------------Element : " << counter << std::endl; //TEST -// counter++; - computeElementLoadVector(localView, muLocal, lambdaLocal, gamma, elementRhs, loadFunctional); -// computeElementLoadVector(localView, muLocal, lambdaLocal, gamma, elementRhs, forceTerm); //TEST -// printvector(std::cout, elementRhs, "elementRhs", "--"); -// printvector(std::cout, elementRhs, "elementRhs", "--"); - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL LOAD ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t p=0; p<localPhiOffset; p++) - { - auto row = localView.index(p); - b[row] += elementRhs[p]; - } - for (size_t m=0; m<3; m++ ) - b[phiOffset+m] += elementRhs[localPhiOffset+m]; - //printvector(std::cout, b, "b", "--"); - } -} - - - -template<class Basis, class LocalFunction1, class LocalFunction2, class MatrixFunction> -auto energy(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - const MatrixFunction& matrixFieldFuncA, - const MatrixFunction& matrixFieldFuncB) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - - auto matrixFieldAGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncA, basis.gridView()); - auto matrixFieldA = localFunction(matrixFieldAGVF); - auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldA.bind(e); - matrixFieldB.bind(e); - mu.bind(e); - lambda.bind(e); - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - auto strain1 = matrixFieldA(quadPos); - auto strain2 = matrixFieldB(quadPos); - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), strain1, strain2); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - -template<class Basis, class Matrix, class Vector, class ParameterSet> -void setOneBaseFunctionToZero(const Basis& basis, - Matrix& stiffnessMatrix, - Vector& load_alpha1, - Vector& load_alpha2, - Vector& load_alpha3, - ParameterSet& parameterSet - ) -{ - std::cout << "Setting one Basis-function to zero" << std::endl; - - constexpr int dim = Basis::LocalView::Element::dimension; - - unsigned int arbitraryLeafIndex = parameterSet.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet.template get<unsigned int>("arbitraryElementNumber", 0); - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - FieldVector<int,3> row = arbitraryComponentwiseIndices(basis,arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k < dim; k++) - { - 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; - } -} - - - -template<class Basis> -auto childToIndexMap(const Basis& basis, - const int k - ) -{ - // Input : child/component - // Output : determine all Indices that belong to that component - auto localView = basis.localView(); - - std::vector<int> r = { }; - // for (int n: r) - // std::cout << n << ","<< std::endl; - - // Determine global indizes for each component k = 1,2,3.. in order to subtract correct (component of) integral Mean - // (global) Indices that correspond to component k = 1,2,3 - for(const auto& element : elements(basis.gridView())) - { - localView.bind(element); - const auto& localFiniteElement = localView.tree().child(k).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - for(size_t j=0; j<nSf; j++) - { - auto Localidx = localView.tree().child(k).localIndex(j); // local indices - r.push_back(localView.index(Localidx)); // global indices - } - } - // Delete duplicate elements - // first remove consecutive (adjacent) duplicates - auto last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - // sort followed by unique, to remove all duplicates - std::sort(r.begin(), r.end()); - last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - - return r; -} - - -template<class Basis, class Vector> -auto integralMean(const Basis& basis, - Vector& coeffVector - ) -{ - // computes integral mean of given LocalFunction - - constexpr int dim = Basis::LocalView::Element::dimension; - - auto GVFunction = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(basis,coeffVector); - auto localfun = localFunction(GVFunction); - - auto localView = basis.localView(); - - FieldVector<double,3> r = {0.0, 0.0, 0.0}; - double area = 0.0; - - // Compute Area integral & integral of FE-function - for(const auto& element : elements(basis.gridView())) - { - localView.bind(element); - localfun.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; //TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - area += quadPoint.weight() * integrationElement; - - r += localfun(quadPos) * quadPoint.weight() * integrationElement; - } - } - // std::cout << "Domain-Area: " << area << std::endl; - return (1.0/area) * r ; -} - - -template<class Basis, class Vector> -auto subtractIntegralMean(const Basis& basis, - Vector& coeffVector - ) -{ - // Substract correct Integral mean from each associated component function - auto IM = integralMean(basis, coeffVector); - - constexpr int dim = Basis::LocalView::Element::dimension; - - for(size_t k=0; k<dim; k++) - { - //std::cout << "Integral-Mean: " << IM[k] << std::endl; - auto idx = childToIndexMap(basis,k); - - for ( int i : idx) - coeffVector[i] -= IM[k]; - } -} - - - -////////////////////////////////////////////////// -// Infrastructure for handling periodicity -////////////////////////////////////////////////// - -// Check whether two points are equal on R/Z x R/Z x R -auto equivalent = [](const FieldVector<double,3>& x, const FieldVector<double,3>& y) - { - return ( (FloatCmp::eq(x[0],y[0]) or FloatCmp::eq(x[0]+1,y[0]) or FloatCmp::eq(x[0]-1,y[0])) - and (FloatCmp::eq(x[1],y[1]) or FloatCmp::eq(x[1]+1,y[1]) or FloatCmp::eq(x[1]-1,y[1])) - and (FloatCmp::eq(x[2],y[2])) - ); - }; - - - -////////////////////////////////////////////////////////////// L2-ERROR ///////////////////////////////////////////////////////////////// -template<class Basis, class Vector, class MatrixFunction> -double computeL2SymError(const Basis& basis, - Vector& coeffVector, - const double gamma, - const MatrixFunction& matrixFieldFunc) -{ - double error = 0.0; - - - auto localView = basis.localView(); - - - constexpr int dim = Basis::LocalView::Element::dimension; //TODO TEST - constexpr int dimWorld = 3; // Hier auch möglich? - - auto matrixFieldGVF = Dune::Functions::makeGridViewFunction(matrixFieldFunc, basis.gridView()); - auto matrixField = localFunction(matrixFieldGVF); - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - matrixField.bind(element); - auto geometry = element.geometry(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; //TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 ); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(quadPos); - const auto integrationElement = geometry.integrationElement(quadPos); - - std::vector< FieldMatrix<double, 1, dim>> referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos,referenceGradients); - - // Compute the shape function gradients on the grid element - std::vector<FieldVector<double,dim>> gradients(referenceGradients.size()); - - for (size_t i=0; i<gradients.size(); i++) - jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]); - - MatrixRT tmp(0); - double sum = 0.0; - - for (size_t k=0; k < dimWorld; k++) - for (size_t i=0; i < nSf; i++) - { - size_t localIdx = localView.tree().child(k).localIndex(i); // hier i:leafIdx - size_t globalIdx = localView.index(localIdx); - - // (scaled) Deformation gradient of the ansatz basis function - MatrixRT defGradientU(0); - defGradientU[k][0] = coeffVector[globalIdx]*gradients[i][0]; // Y //hier i:leafIdx - defGradientU[k][1] = coeffVector[globalIdx]*gradients[i][1]; //X2 - defGradientU[k][2] = coeffVector[globalIdx]*(1.0/gamma)*gradients[i][2]; //X3 - - tmp += sym(defGradientU); - } -// printmatrix(std::cout, matrixField(quadPos), "matrixField(quadPos)", "--"); -// printmatrix(std::cout, tmp, "tmp", "--"); // TEST Symphi_1 hat andere Struktur als analytic? -// tmp = tmp - matrixField(quadPos); -// printmatrix(std::cout, tmp - matrixField(quadPos), "Difference", "--"); - for (int ii=0; ii<dimWorld; ii++) - for (int jj=0; jj<dimWorld; jj++) - { - sum += std::pow(tmp[ii][jj]-matrixField(quadPos)[ii][jj],2); - } -// std::cout << "sum:" << sum << std::endl; - error += sum * quadPoint.weight() * integrationElement; -// std::cout << "error:" << error << std::endl; - } - } - return sqrt(error); -} -////////////////////////////////////////////////////////////// L2-NORM ///////////////////////////////////////////////////////////////// -template<class Basis, class Vector> -double computeL2Norm(const Basis& basis, - Vector& coeffVector) -{ - // IMPLEMENTATION with makeDiscreteGlobalBasisFunction - double error = 0.0; - - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - auto localView = basis.localView(); - auto GVFunc = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(basis,coeffVector); - auto localfun = localFunction(GVFunc); - - for(const auto& element : elements(basis.gridView())) - { - localView.bind(element); - localfun.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; //TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - error += localfun(quadPos)*localfun(quadPos) * quadPoint.weight() * integrationElement; - } - } - return sqrt(error); -} - - - - - - -template<class Basis,class LocalFunction1, class LocalFunction2, class GVFunction , class MatrixFunction, class Matrix> -auto test_derivative(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - const double& gamma, - Matrix& M, - const GVFunction& matrixFieldFuncA, -// const GVFunction& matrixFieldA, - const MatrixFunction& matrixFieldFuncB - ) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - -// auto matrixFieldAGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncA, basis.gridView()); - auto matrixFieldA = localFunction(matrixFieldFuncA); - auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldA.bind(e); - matrixFieldB.bind(e); - mu.bind(e); - lambda.bind(e); - - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - auto strain1 = matrixFieldA(quadPos); - auto strain2 = matrixFieldB(quadPos); -// printmatrix(std::cout, strain1 , "strain1", "--"); - - //cale with GAMMA - strain1 = crossSectionDirectionScaling(1.0/gamma, strain1); - strain1 = sym(strain1); - // ADD M - auto test = strain1 + *M ; -// std::cout << "test:" << test << std::endl; - -// for (size_t m=0; m<3; m++ ) -// for (size_t n=0; n<3; n++ ) -// strain1[m][n] += M[m][n]; - - - -// double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), strain1, strain2); - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), test, strain2); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - - -// elementEnergy += strain1 * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - - - -template<class Basis, class LocalFunction1, class LocalFunction2, class MatrixFunction, class Matrix> -auto energy_MG(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - Matrix& M, - const MatrixFunction& matrixFieldFuncB) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - -// auto matrixFieldAGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncA, basis.gridView()); -// auto matrixFieldA = localFunction(matrixFieldAGVF); - auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); -// matrixFieldA.bind(e); - matrixFieldB.bind(e); - mu.bind(e); - lambda.bind(e); - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - -// auto strain1 = matrixFieldA(quadPos); - auto strain2 = matrixFieldB(quadPos); - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), *M, strain2); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - - - - - - - -template<class Basis,class LocalFunction1, class LocalFunction2, class GVFunction , class MatrixFunction, class Matrix> -auto check_Orthogonality(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - const double& gamma, - Matrix& M1, - Matrix& M2, - const GVFunction& DerPhi_1, - const GVFunction& DerPhi_2, -// const GVFunction& matrixFieldA, - const MatrixFunction& matrixFieldFuncG - ) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - - - auto DerPhi1 = localFunction(DerPhi_1); - auto DerPhi2 = localFunction(DerPhi_2); - - auto matrixFieldGGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncG, basis.gridView()); - auto matrixFieldG = localFunction(matrixFieldGGVF); -// auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); -// auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - -// std::cout << "Press key.." << std::endl; -// std::cin.get(); - -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldG.bind(e); - DerPhi1.bind(e); - DerPhi2.bind(e); - mu.bind(e); - lambda.bind(e); - - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - - auto Chi = sym(crossSectionDirectionScaling(1.0/gamma, DerPhi2(quadPos))) + *M2; - - auto strain1 = DerPhi1(quadPos); -// printmatrix(std::cout, strain1 , "strain1", "--"); - //cale with GAMMA - strain1 = crossSectionDirectionScaling(1.0/gamma, strain1); - strain1 = sym(strain1); - - - // ADD M -// auto test = strain1 + *M ; -// std::cout << "test:" << test << std::endl; - -// for (size_t m=0; m<3; m++ ) -// for (size_t n=0; n<3; n++ ) -// strain1[m][n] += M[m][n]; - - auto G = matrixFieldG(quadPos); -// auto G = matrixFieldG(e.geometry().global(quadPos)); //TEST - - - auto tmp = G + *M1 + strain1; - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), tmp, Chi); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - - -// elementEnergy += strain1 * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - - -template<class Basis,class LocalFunction1, class LocalFunction2, class GVFunction , class MatrixFunction, class Matrix> -auto computeFullQ(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - const double& gamma, - Matrix& M1, - Matrix& M2, - const GVFunction& DerPhi_1, - const GVFunction& DerPhi_2, -// const GVFunction& matrixFieldA, - const MatrixFunction& matrixFieldFuncG1, - const MatrixFunction& matrixFieldFuncG2 - ) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - - - auto DerPhi1 = localFunction(DerPhi_1); - auto DerPhi2 = localFunction(DerPhi_2); - - auto matrixFieldG1GVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncG1, basis.gridView()); - auto matrixFieldG1 = localFunction(matrixFieldG1GVF); - auto matrixFieldG2GVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncG2, basis.gridView()); - auto matrixFieldG2 = localFunction(matrixFieldG2GVF); -// auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); -// auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldG1.bind(e); - matrixFieldG2.bind(e); - DerPhi1.bind(e); - DerPhi2.bind(e); - mu.bind(e); - lambda.bind(e); - - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); -// int orderQR = 0; -// int orderQR = 1; -// int orderQR = 2; -// int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - auto Chi1 = sym(crossSectionDirectionScaling(1.0/gamma, DerPhi1(quadPos))) + *M1; - auto Chi2 = sym(crossSectionDirectionScaling(1.0/gamma, DerPhi2(quadPos))) + *M2; - -// auto strain1 = DerPhi1(quadPos); -// // printmatrix(std::cout, strain1 , "strain1", "--"); -// //cale with GAMMA -// strain1 = crossSectionDirectionScaling(1.0/gamma, strain1); -// strain1 = sym(strain1); - - - // ADD M -// auto test = strain1 + *M ; -// std::cout << "test:" << test << std::endl; - -// for (size_t m=0; m<3; m++ ) -// for (size_t n=0; n<3; n++ ) -// strain1[m][n] += M[m][n]; - - auto G1 = matrixFieldG1(quadPos); - auto G2 = matrixFieldG2(quadPos); -// auto G1 = matrixFieldG1(e.geometry().global(quadPos)); //TEST -// auto G2 = matrixFieldG2(e.geometry().global(quadPos)); //TEST - - auto X1 = G1 + Chi1; - auto X2 = G2 + Chi2; - - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), X1, X2); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; // quad[quadPoint].weight() ??? - - -// elementEnergy += strain1 * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int main(int argc, char *argv[]) -{ - MPIHelper::instance(argc, argv); - - Dune::Timer globalTimer; - - ParameterTree parameterSet; - if (argc < 2) - ParameterTreeParser::readINITree("../../inputs/cellsolver.parset", parameterSet); - else - { - ParameterTreeParser::readINITree(argv[1], parameterSet); - ParameterTreeParser::readOptions(argc, argv, parameterSet); - } - - //--- Output setter -// std::string outputPath = parameterSet.get("outputPath", "../../outputs/output.txt"); -// std::string outputPath = parameterSet.get("outputPath", "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt"); -// std::string outputPath = parameterSet.get("outputPath", "/home/klaus/Desktop/DUNE/dune-microstructure/outputs"); - std::string outputPath = parameterSet.get("outputPath", "../../outputs"); -// std::string MatlabPath = parameterSet.get("MatlabPath", "/home/klaus/Desktop/DUNE/dune-microstructure/Matlab-Programs"); -// std::string outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt"; - std::fstream log; - log.open(outputPath + "/output.txt" ,std::ios::out); - - std::cout << "outputPath:" << outputPath << std::endl; - -// parameterSet.report(log); // short Alternativ - - - std::string geometryFunctionPath = parameterSet.get<std::string>("geometryFunctionPath"); - //Start Python interpreter - Python::start(); - Python::Reference main = Python::import("__main__"); - Python::run("import math"); - - //"sys.path.append('/home/klaus/Desktop/DUNE/dune-gfe/problems')" - Python::runStream() - << std::endl << "import sys" - << std::endl << "sys.path.append('" << geometryFunctionPath << "')" - << std::endl; -// -// // Use python-function for initialIterate -// // Read initial iterate into a Python function -// Python::Module module = Python::import(parameterSet.get<std::string>("geometryFunction")); -// auto pythonInitialIterate = Python::make_function<double>(module.get("f")); - - - - std::cout << "machine epsilon:" << std::numeric_limits<double>::epsilon() << std::endl; - - constexpr int dim = 3; - constexpr int dimWorld = 3; - - /////////////////////////////////// - // Get Parameters/Data - /////////////////////////////////// - double gamma = parameterSet.get<double>("gamma",1.0); // ratio dimension reduction to homogenization - double alpha = parameterSet.get<double>("alpha", 2.0); - double theta = parameterSet.get<double>("theta",1.0/4.0); - /////////////////////////////////// - // Get Material Parameters - /////////////////////////////////// - std::string imp = parameterSet.get<std::string>("material_prestrain_imp", "analytical_Example"); - log << "material_prestrain used: "<< imp << std::endl; - double beta = parameterSet.get<double>("beta",2.0); - double mu1 = parameterSet.get<double>("mu1",1.0);; - double mu2 = beta*mu1; - double lambda1 = parameterSet.get<double>("lambda1",0.0);; - double lambda2 = beta*lambda1; - - // Plate geometry settings - double width = parameterSet.get<double>("width", 1.0); //geometry cell, cross section - // double len = parameterSet.get<double>("len", 10.0); //length - // double height = parameterSet.get<double>("h", 0.1); //rod thickness - // double eps = parameterSet.get<double>("eps", 0.1); //size of perioticity cell - - if(imp == "material_neukamm") - { - std::cout <<"mu: " <<parameterSet.get<std::array<double,3>>("mu", {1.0,3.0,2.0}) << std::endl; - std::cout <<"lambda: " << parameterSet.get<std::array<double,3>>("lambda", {1.0,3.0,2.0}) << std::endl; - } - else - { - std::cout <<"mu: " << parameterSet.get<double>("mu1",1.0) << std::endl; - std::cout <<"lambda: " << parameterSet.get<double>("lambda1",0.0) << std::endl; - } - - - - /////////////////////////////////// - // Get Prestrain/Parameters - /////////////////////////////////// -// unsigned int prestraintype = parameterSet.get<unsigned int>("prestrainType", "analytical_Example"); //OLD -// std::string prestraintype = parameterSet.get<std::string>("prestrainType", "analytical_Example"); -// double rho1 = parameterSet.get<double>("rho1", 1.0); -// double rho2 = alpha*rho1; -// auto prestrainImp = PrestrainImp(rho1, rho2, theta, width); -// auto B_Term = prestrainImp.getPrestrain(prestraintype); - - - - auto prestrainImp = PrestrainImp<dim>(); //NEW - auto B_Term = prestrainImp.getPrestrain(parameterSet); - - log << "----- Input Parameters -----: " << std::endl; -// log << "prestrain imp: " << prestraintype << "\nrho1 = " << rho1 << "\nrho2 = " << rho2 << std::endl; - log << "alpha: " << alpha << std::endl; - log << "gamma: " << gamma << std::endl; - log << "theta: " << theta << std::endl; - log << "beta: " << beta << std::endl; - log << "material parameters: " << std::endl; - log << "mu1: " << mu1 << "\nmu2: " << mu2 << std::endl; - log << "lambda1: " << lambda1 <<"\nlambda2: " << lambda2 << std::endl; - log << "----------------------------: " << std::endl; - - /////////////////////////////////// - // Generate the grid - /////////////////////////////////// - - //Corrector Problem Domain: - unsigned int cellDomain = parameterSet.get<unsigned int>("cellDomain", 1); - // (shifted) Domain (-1/2,1/2)^3 - FieldVector<double,dim> lower({-1.0/2.0, -1.0/2.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0/2.0, 1.0/2.0, 1.0/2.0}); - if (cellDomain == 2) - { - // Domain : [0,1)^2 x (-1/2, 1/2) - FieldVector<double,dim> lower({0.0, 0.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0, 1.0, 1.0/2.0}); - } - - std::array<int,2> numLevels = parameterSet.get<std::array<int,2>>("numLevels", {1,3}); - - int levelCounter = 0; - - -// FieldVector<double,2> mu = parameterSet.get<FieldVector<double,2>>("mu", {1.0,3.0}); - - /////////////////////////////////// - // Create Data Storage - /////////////////////////////////// - // Storage:: #1 level #2 L2SymError #3 L2SymErrorOrder #4 L2Norm(sym) #5 L2Norm(sym-analytic) #6 L2Norm(phi_1) - std::vector<std::variant<std::string, size_t , double>> Storage_Error; - - // Storage:: #1 level #2 |q1_a-q1_c| #3 |q2_a-q2_c| #4 |q3_a-q3_c| #5 |b1_a-b1_c| #6 |b2_a-b2_c| #7 |b3_a-b3_c| - std::vector<std::variant<std::string, size_t , double>> Storage_Quantities; - - -// for(const size_t &level : numLevels) // explixite Angabe der levels.. {2,4} - for(size_t level = numLevels[0] ; level <= numLevels[1]; level++) // levels von bis.. [2,4] - { - std::cout << " ----------------------------------" << std::endl; - std::cout << "Level: " << level << std::endl; - std::cout << " ----------------------------------" << std::endl; - - Storage_Error.push_back(level); - Storage_Quantities.push_back(level); - std::array<int, dim> nElements = { (int)std::pow(2,level) , (int)std::pow(2,level) , (int)std::pow(2,level) }; - -// std::array<unsigned int, dim> nElements_test = { (int)std::pow(2,level) , (int)std::pow(2,level) , (int)std::pow(2,level) }; - - std::cout << "Number of Elements in each direction: " << nElements << std::endl; - log << "Number of Elements in each direction: " << nElements << std::endl; - - using CellGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; - CellGridType grid_CE(lower,upper,nElements); - using GridView = CellGridType::LeafGridView; - const GridView gridView_CE = grid_CE.leafGridView(); - std::cout << "Host grid has " << gridView_CE.size(dim) << " vertices." << std::endl; - - - //TEST -// using CellGridTypeT = StructuredGridFactory<UGGrid<dim> >; -// auto grid = StructuredGridFactory<UGGrid<dim> >::createCubeGrid(lower,upper,nElements_test); -// auto gridView_CE = grid::leafGridView(); - -// FieldVector<double,3> lowerLeft = {0.0, 0.0, 0.0}; -// FieldVector<double,3> upperRight = {1.0, 1.0, 1.0}; -// std::array<unsigned int,3> elements = {10, 10, 10}; -// auto grid = StructuredGridFactory<UGGrid<3> >::createCubeGrid(lowerLeft, -// upperRight, -// elements); -// - - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - using Domain = GridView::Codim<0>::Geometry::GlobalCoordinate; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - using VectorCT = BlockVector<FieldVector<double,1> >; - using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - - /////////////////////////////////// - // Create Lambda-Functions for material Parameters depending on microstructure - /////////////////////////////////// - auto materialImp = IsotropicMaterialImp<dim>(); - auto muTerm = materialImp.getMu(parameterSet); - auto lambdaTerm = materialImp.getLambda(parameterSet); - -/* - auto muTerm = [mu1, mu2, theta] (const Domain& z) { - if (abs(z[0]) >= (theta/2.0)) - return mu1; - else - return mu2; - }; - - auto lambdaTerm = [lambda1,lambda2, theta] (const Domain& z) { - if (abs(z[0]) >= (theta/2.0)) - return lambda1; - else - return lambda2; - };*/ - auto muGridF = Dune::Functions::makeGridViewFunction(muTerm, gridView_CE); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambdaTerm, gridView_CE); - auto lambdaLocal = localFunction(lambdaGridF); - - /////////////////////////////////// - // --- Choose Solver --- - // 1 : CG-Solver - // 2 : GMRES - // 3 : QR - /////////////////////////////////// - unsigned int Solvertype = parameterSet.get<unsigned int>("Solvertype", 3); - - unsigned int Solver_verbosity = parameterSet.get<unsigned int>("Solver_verbosity", 2); - - // Print Options - bool print_debug = parameterSet.get<bool>("print_debug", false); - - //VTK-Write - bool write_materialFunctions = parameterSet.get<bool>("write_materialFunctions", false); - bool write_prestrainFunctions = parameterSet.get<bool>("write_prestrainFunctions", false); - bool write_corrector_phi1 = parameterSet.get<bool>("write_corrector_phi1", false); - bool write_corrector_phi2 = parameterSet.get<bool>("write_corrector_phi2", false); - bool write_corrector_phi3 = parameterSet.get<bool>("write_corrector_phi3", false); - bool write_L2Error = parameterSet.get<bool>("write_L2Error", false); - bool write_IntegralMean = parameterSet.get<bool>("write_IntegralMean", false); - bool write_VTK = parameterSet.get<bool>("write_VTK", false); - - ///////////////////////////////////////////////////////// - // Choose a finite element space for Cell Problem - ///////////////////////////////////////////////////////// - using namespace Functions::BasisFactory; - Functions::BasisFactory::Experimental::PeriodicIndexSet periodicIndices; - - // Don't do the following in real life: It has quadratic run-time in the number of vertices. - for (const auto& v1 : vertices(gridView_CE)) - for (const auto& v2 : vertices(gridView_CE)) - if (equivalent(v1.geometry().corner(0), v2.geometry().corner(0))) - { - periodicIndices.unifyIndexPair({gridView_CE.indexSet().index(v1)}, {gridView_CE.indexSet().index(v2)}); - } - - // First order periodic Lagrange-Basis - auto Basis_CE = makeBasis( - gridView_CE, - power<dim>( // eig dimworld?!?! - Functions::BasisFactory::Experimental::periodic(lagrange<1>(), periodicIndices), - flatLexicographic() -// blockedInterleaved() // ERROR - )); - - std::cout << "power<periodic> basis has " << Basis_CE.dimension() << " degrees of freedom" << std::endl; - - log << "size of FiniteElementBasis: " << Basis_CE.size() << std::endl; - const int phiOffset = Basis_CE.size(); - - ///////////////////////////////////////////////////////// - // Data structures: Stiffness matrix and right hand side vectors - ///////////////////////////////////////////////////////// - VectorCT load_alpha1, load_alpha2, load_alpha3; - MatrixCT stiffnessMatrix_CE; - - bool set_IntegralZero = parameterSet.get<bool>("set_IntegralZero", false); - bool set_oneBasisFunction_Zero = parameterSet.get<bool>("set_oneBasisFunction_Zero", false); -// bool set_oneBasisFunction_Zero = false; - bool substract_integralMean = false; - if(set_IntegralZero) - { - set_oneBasisFunction_Zero = true; - substract_integralMean = true; - } - - ///////////////////////////////////////////////////////// - // Define "rhs"-functions - ///////////////////////////////////////////////////////// - Func2Tensor x3G_1 = [] (const Domain& x) { - return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - }; - - Func2Tensor x3G_2 = [] (const Domain& x) { - return MatrixRT{{0.0, 0.0, 0.0}, {0.0, 1.0*x[2], 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_3 = [] (const Domain& x) { - return MatrixRT{{0.0, (1.0/sqrt(2.0))*x[2], 0.0}, {(1.0/sqrt(2.0))*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_1neg = [x3G_1] (const Domain& x) {return -1.0*x3G_1(x);}; - Func2Tensor x3G_2neg = [x3G_2] (const Domain& x) {return -1.0*x3G_2(x);}; - Func2Tensor x3G_3neg = [x3G_3] (const Domain& x) {return -1.0*x3G_3(x);}; - - //TODO eigentlich funtkioniert es ja mit x3G_1 etc doch auch ?! - - - - - - //TEST -// std::cout << "Test crossSectionDirectionScaling:" << std::endl; -/* - MatrixRT T {{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}; - printmatrix(std::cout, T, "Matrix T", "--"); - - auto ST = crossSectionDirectionScaling((1.0/5.0),T); - printmatrix(std::cout, ST, "scaled Matrix T", "--");*/ - - //TEST -// auto QuadraticForm = [] (const double mu, const double lambda, const MatrixRT& M) { -// -// return lambda*std::pow(trace(M),2) + 2*mu*pow(norm(sym(M)),2); -// }; - - - // TEST - energy method /// - // different indicatorFunction in muTerm has impact here !! - // double GGterm = 0.0; - // GGterm = energy(Basis_CE, muLocal, lambdaLocal, x3G_1, x3G_1 ); // <L i(x3G_alpha) , i(x3G_beta) > - // std::cout << "GGTerm:" << GGterm << std::endl; - // std::cout << " analyticGGTERM:" << (mu1*(1-theta)+mu2*theta)/6.0 << std::endl; - - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - 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, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 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", "--"); - // log << basisContainer[0] << std::endl; - - - ////////////////////////////////////////////////////////////////////// - // Determine global indices of components for arbitrary (local) index - ////////////////////////////////////////////////////////////////////// - int arbitraryLeafIndex = parameterSet.get<unsigned int>("arbitraryLeafIndex", 0); // localIdx..assert Number < #ShapeFcts - int arbitraryElementNumber = parameterSet.get<unsigned int>("arbitraryElementNumber", 0); - - - if(print_debug) - { - FieldVector<int,3> row; - row = arbitraryComponentwiseIndices(Basis_CE,arbitraryElementNumber,arbitraryLeafIndex); - printvector(std::cout, row, "row" , "--"); - } - - ///////////////////////////////////////////////////////// - // Assemble the system - ///////////////////////////////////////////////////////// - Dune::Timer StiffnessTimer; - assembleCellStiffness(Basis_CE, muLocal, lambdaLocal, gamma, stiffnessMatrix_CE, parameterSet); - std::cout << "Stiffness assembly Timer: " << StiffnessTimer.elapsed() << std::endl; - assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha1 ,x3G_1neg); - assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha2 ,x3G_2neg); - assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha3 ,x3G_3neg); - //TEST -// assembleCellStiffness(Basis_CE, muTerm, lambdaTerm, gamma, stiffnessMatrix_CE, parameterSet); -// std::cout << "Stiffness assembly Timer: " << StiffnessTimer.elapsed() << std::endl; -// assembleCellLoad(Basis_CE, muTerm, lambdaTerm,gamma, load_alpha1 ,x3G_1neg); -// assembleCellLoad(Basis_CE, muTerm, lambdaTerm,gamma, load_alpha2 ,x3G_2neg); -// assembleCellLoad(Basis_CE, muTerm, lambdaTerm,gamma, load_alpha3 ,x3G_3neg); - - //TEST -// assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha1 ,x3G_1); -// assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha2 ,x3G_2); -// assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha3 ,x3G_3); -// printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix", "--"); -// printvector(std::cout, load_alpha1, "load_alpha1", "--"); - - //TODO Add Option for this - // CHECK SYMMETRY: -// checkSymmetry(Basis_CE,stiffnessMatrix_CE); - - - - - // set one basis-function to zero - if(set_oneBasisFunction_Zero) - { - setOneBaseFunctionToZero(Basis_CE, stiffnessMatrix_CE, load_alpha1, load_alpha2, load_alpha3, parameterSet); - // printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix after setOneBasisFunctionToZero", "--"); -// printvector(std::cout, load_alpha1, "load_alpha1 after setOneBaseFunctionToZero", "--"); - } - - //TEST: Compute Condition Number (Can be very expensive !) - const bool verbose = true; - const unsigned int arppp_a_verbosity_level = 2; - const unsigned int pia_verbosity_level = 1; - MatrixInfo<MatrixCT> matrixInfo(stiffnessMatrix_CE,verbose,arppp_a_verbosity_level,pia_verbosity_level); - std::cout << "Get condition number of Stiffness_CE: " << matrixInfo.getCond2(true) << std::endl; -// std::cout << "Get condition number of Stiffness_CE: " << matrixInfo.getCond2(false) << std::endl; - - //////////////////////////////////////////////////// - // Compute solution - //////////////////////////////////////////////////// - VectorCT x_1 = load_alpha1; - VectorCT x_2 = load_alpha2; - VectorCT x_3 = load_alpha3; - -// auto load_alpha1BS = load_alpha1; - // printvector(std::cout, load_alpha1, "load_alpha1 before SOLVER", "--" ); - // printvector(std::cout, load_alpha2, "load_alpha2 before SOLVER", "--" ); - - if (Solvertype == 1) // CG - SOLVER - { - std::cout << "------------ CG - Solver ------------" << std::endl; - MatrixAdapter<MatrixCT, VectorCT, VectorCT> op(stiffnessMatrix_CE); - - - - // Sequential incomplete LU decomposition as the preconditioner - SeqILU<MatrixCT, VectorCT, VectorCT> ilu0(stiffnessMatrix_CE,1.0); - int iter = parameterSet.get<double>("iterations_CG", 999); - // Preconditioned conjugate-gradient solver - CGSolver<VectorCT> solver(op, - ilu0, //NULL, - 1e-8, // desired residual reduction factorlack - iter, // maximum number of iterations - Solver_verbosity, - true // Try to estimate condition_number - ); // verbosity of the solver - InverseOperatorResult statistics; - std::cout << "solve linear system for x_1.\n"; - solver.apply(x_1, load_alpha1, statistics); - std::cout << "solve linear system for x_2.\n"; - solver.apply(x_2, load_alpha2, statistics); - std::cout << "solve linear system for x_3.\n"; - solver.apply(x_3, load_alpha3, statistics); - log << "Solver-type used: " <<" CG-Solver" << std::endl; - - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - - else if (Solvertype ==2) // GMRES - SOLVER - { - - std::cout << "------------ GMRES - Solver ------------" << std::endl; - // Turn the matrix into a linear operator - MatrixAdapter<MatrixCT,VectorCT,VectorCT> stiffnessOperator(stiffnessMatrix_CE); - - // Fancy (but only) way to not have a preconditioner at all - Richardson<VectorCT,VectorCT> preconditioner(1.0); - - // Construct the iterative solver - RestartedGMResSolver<VectorCT> solver( - stiffnessOperator, // Operator to invert - preconditioner, // Preconditioner - 1e-10, // Desired residual reduction factor - 500, // Number of iterations between restarts, - // here: no restarting - 500, // Maximum number of iterations - Solver_verbosity); // Verbosity of the solver - - // Object storing some statistics about the solving process - InverseOperatorResult statistics; - - // solve for different Correctors (alpha = 1,2,3) - solver.apply(x_1, load_alpha1, statistics); //load_alpha1 now contains the corresponding residual!! - solver.apply(x_2, load_alpha2, statistics); - solver.apply(x_3, load_alpha3, statistics); - log << "Solver-type used: " <<" GMRES-Solver" << std::endl; - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if ( Solvertype == 3)// QR - SOLVER - { - - std::cout << "------------ QR - Solver ------------" << std::endl; - log << "solveLinearSystems: We use QR solver.\n"; - //TODO install suitesparse - SPQR<MatrixCT> sPQR(stiffnessMatrix_CE); - sPQR.setVerbosity(1); - InverseOperatorResult statisticsQR; - - sPQR.apply(x_1, load_alpha1, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_2, load_alpha2, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_3, load_alpha3, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log << "Solver-type used: " <<" QR-Solver" << std::endl; - - - } - else if ( Solvertype == 4)// UMFPACK - SOLVER - { - - std::cout << "------------ UMFPACK - Solver ------------" << std::endl; - log << "solveLinearSystems: We use UMFPACK solver.\n"; - - Dune::Solvers::UMFPackSolver<MatrixCT,VectorCT> solver; - solver.setProblem(stiffnessMatrix_CE,x_1,load_alpha1); -// solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_CE,x_2,load_alpha2); -// solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_CE,x_3,load_alpha3); -// solver.preprocess(); - solver.solve(); - -// sPQR.apply(x_1, load_alpha1, statisticsQR); -// std::cout << "statistics.converged " << statisticsQR.converged << std::endl; -// std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; -// std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; -// sPQR.apply(x_2, load_alpha2, statisticsQR); -// std::cout << "statistics.converged " << statisticsQR.converged << std::endl; -// std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; -// std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; -// sPQR.apply(x_3, load_alpha3, statisticsQR); -// std::cout << "statistics.converged " << statisticsQR.converged << std::endl; -// std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; -// std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log << "Solver-type used: " <<" UMFPACK-Solver" << std::endl; - - - } - // printvector(std::cout, load_alpha1BS, "load_alpha1 before SOLVER", "--" ); - // printvector(std::cout, load_alpha1, "load_alpha1 AFTER SOLVER", "--" ); - // printvector(std::cout, load_alpha2, "load_alpha2 AFTER SOLVER", "--" ); - - //////////////////////////////////////////////////////////////////////////////////// - // 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; - - 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]; - } - - FieldVector<double,3> m_1, m_2, m_3; - - 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]; - } - // 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]; - } - - std::cout << "--- plot corrector-Matrices M_alpha --- " << std::endl; - printmatrix(std::cout, M_1, "Corrector-Matrix M_1", "--"); - printmatrix(std::cout, M_2, "Corrector-Matrix M_2", "--"); - printmatrix(std::cout, M_3, "Corrector-Matrix M_3", "--"); - log << "---------- OUTPUT ----------" << std::endl; - log << " --------------------" << std::endl; - log << "Corrector-Matrix M_1: \n" << M_1 << std::endl; - log << " --------------------" << std::endl; - log << "Corrector-Matrix M_2: \n" << M_2 << std::endl; - log << " --------------------" << std::endl; - log << "Corrector-Matrix M_3: \n" << M_3 << std::endl; - log << " --------------------" << std::endl; - - - - - //////////////////////////////////////////////////////////////////////////// - // Substract Integral-mean - //////////////////////////////////////////////////////////////////////////// - using SolutionRange = FieldVector<double,dim>; - - if(write_IntegralMean) - { - std::cout << "check integralMean phi_1: " << std::endl; - auto A = integralMean(Basis_CE,phi_1); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean : " << A[i] << std::endl; - } - } - if(substract_integralMean) - { - std::cout << " --- substracting integralMean --- " << std::endl; - subtractIntegralMean(Basis_CE, phi_1); - subtractIntegralMean(Basis_CE, phi_2); - subtractIntegralMean(Basis_CE, phi_3); - subtractIntegralMean(Basis_CE, x_1); - subtractIntegralMean(Basis_CE, x_2); - subtractIntegralMean(Basis_CE, x_3); - ////////////////////////////////////////// - // CHECK INTEGRAL-MEAN: - ////////////////////////////////////////// - if(write_IntegralMean) - { - auto A = integralMean(Basis_CE, phi_1); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean (CHECK) : " << A[i] << std::endl; - } - } - } - - ///////////////////////////////////////////////////////// - // Write Solution (Corrector Coefficients) in Logs - ///////////////////////////////////////////////////////// -// log << "\nSolution of Corrector problems:\n"; - if(write_corrector_phi1) - { - log << "\nSolution of Corrector problems:\n"; - log << "\n Corrector_phi1:\n"; - log << x_1 << std::endl; - } - if(write_corrector_phi2) - { - log << "-----------------------------------------------------"; - log << "\n Corrector_phi2:\n"; - log << x_2 << std::endl; - } - if(write_corrector_phi3) - { - log << "-----------------------------------------------------"; - log << "\n Corrector_phi3:\n"; - log << x_3 << std::endl; - } - - //////////////////////////////////////////////////////////////////////////// - // Make a discrete function from the FE basis and the coefficient vector - //////////////////////////////////////////////////////////////////////////// // ERROR - auto correctorFunction_1 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( - Basis_CE, - phi_1); - - auto correctorFunction_2 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( - Basis_CE, - phi_2); - - auto correctorFunction_3 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( - Basis_CE, - phi_3); - - ///////////////////////////////////////////////////////// - // Create Containers for Basis-Matrices, Correctors and Coefficients - ///////////////////////////////////////////////////////// - const std::array<Func2Tensor, 3> x3MatrixBasis = {x3G_1, x3G_2, x3G_3}; - const std::array<VectorCT, 3> coeffContainer = {x_1, x_2, x_3}; - const std::array<VectorCT, 3> loadContainer = {load_alpha1, load_alpha2, load_alpha3}; - const std::array<MatrixRT*, 3 > mContainer = {&M_1 , &M_2, & M_3}; - - //TEST - - auto zeroFunction = [] (const Domain& x) { - return MatrixRT{{0.0 , 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - auto L2Norm_1 = computeL2Norm(Basis_CE,phi_1); - auto L2Norm_Symphi_1 = computeL2SymError(Basis_CE,phi_1,gamma,zeroFunction); - auto L2Norm_2 = computeL2Norm(Basis_CE,phi_2); - auto L2Norm_Symphi_2 = computeL2SymError(Basis_CE,phi_2,gamma,zeroFunction); - auto L2Norm_3 = computeL2Norm(Basis_CE,phi_3); - auto L2Norm_Symphi_3 = computeL2SymError(Basis_CE,phi_3,gamma,zeroFunction); - - std::cout<< "L2Norm - Corrector 1: " << L2Norm_1 << std::endl; - std::cout<< "L2Norm (symgrad) - Corrector 1: " << L2Norm_Symphi_1 << std::endl; - std::cout<< "L2Norm - Corrector 2: " << L2Norm_2 << std::endl; - std::cout<< "L2Norm (symgrad) - Corrector 2: " << L2Norm_Symphi_2 << std::endl; - std::cout<< "L2Norm - Corrector 3: " << L2Norm_3 << std::endl; - std::cout<< "L2Norm (symgrad) - Corrector 3: " << L2Norm_Symphi_3 << std::endl; - - std::cout<< "Frobenius-Norm of M_1: " << M_1.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M_2: " << M_2.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M_3: " << M_3.frobenius_norm() << std::endl; - - //TEST - -// auto local_cor1 = localFunction(correctorFunction_1); -// auto local_cor2 = localFunction(correctorFunction_2); -// auto local_cor3 = localFunction(correctorFunction_3); -// -// auto Der1 = derivative(local_cor1); -// auto Der2 = derivative(local_cor2); -// auto Der3 = derivative(local_cor3); - - auto Der1 = derivative(correctorFunction_1); - auto Der2 = derivative(correctorFunction_2); - auto Der3 = derivative(correctorFunction_3); - - const std::array<decltype(Der1)*,3> phiDerContainer = {&Der1, &Der2, &Der3}; - -// auto output_der = test_derivative(Basis_CE,Der1); - - -// std::cout << "evaluate derivative " << output_der << std::endl; - - - - // TODO : MOVE All of this into a separate class : 'computeEffectiveQuantities' - ///////////////////////////////////////////////////////// - // Compute effective quantities: Elastic law & Prestrain - ///////////////////////////////////////////////////////// - MatrixRT Q(0); - VectorCT tmp1,tmp2; - FieldVector<double,3> B_hat ; - - - - //VARIANT 1 - //Compute effective elastic law Q - for(size_t a = 0; a < 3; a++) - for(size_t b=0; b < 3; b++) - { - assembleCellLoad(Basis_CE, muLocal, lambdaLocal, gamma, tmp1 ,x3MatrixBasis[b]); // <L i(M_alpha) + sym(grad phi_alpha), i(x3G_beta) > - - double GGterm = 0.0; - double MGterm = 0.0; - GGterm = energy(Basis_CE, muLocal, lambdaLocal, x3MatrixBasis[a] , x3MatrixBasis[b] ); // <L i(x3G_alpha) , i(x3G_beta) > - MGterm = energy_MG(Basis_CE, muLocal, lambdaLocal, mContainer[a], x3MatrixBasis[b]); - - double tmp = 0.0; - - tmp = test_derivative(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],*phiDerContainer[a],x3MatrixBasis[b]); - - - - std::cout << "---- (" << a << "," << b << ") ---- " << std::endl; - - std::cout << "check_Orthogonality:" << check_Orthogonality(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[b],*phiDerContainer[a],*phiDerContainer[b],x3MatrixBasis[a]) << std::endl; - - - - -// if(a==0) -// { -// tmp = test_derivative(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],Der1,x3MatrixBasis[b]); -// std::cout << "check_Orthogonality:" << check_Orthogonality(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[1],Der1,Der2,x3MatrixBasis[a]) << std::endl; -// } -// else if (a==1) -// { -// tmp = test_derivative(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],Der2,x3MatrixBasis[b]); -// std::cout << "check_Orthogonality:" << check_Orthogonality(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[1],Der2,Der2,x3MatrixBasis[a]) << std::endl; -// } -// else -// { -// tmp = test_derivative(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],Der3,x3MatrixBasis[b]); -// std::cout << "check_Orthogonality:" << check_Orthogonality(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[1],Der3,Der2,x3MatrixBasis[a]) << std::endl; -// } - - - std::cout << "GGTerm:" << GGterm << std::endl; - std::cout << "MGTerm:" << MGterm << std::endl; - std::cout << "tmp:" << tmp << std::endl; - std::cout << "(coeffContainer[a]*tmp1):" << (coeffContainer[a]*tmp1) << std::endl; - - - // TEST - // std::setprecision(std::numeric_limits<float>::digits10); - -// Q[a][b] = (coeffContainer[a]*tmp1) + GGterm; // seems symmetric...check positiv definitness? - Q[a][b] = tmp + GGterm; // TODO : Zusammenfassen in einer Funktion ... - - if (print_debug) - { - std::cout << "analyticGGTERM:" << (mu1*(1-theta)+mu2*theta)/6.0 << std::endl; - std::cout << "GGTerm:" << GGterm << std::endl; - std::cout << "coeff*tmp: " << coeffContainer[a]*tmp1 << std::endl; - } - } - printmatrix(std::cout, Q, "Matrix Q", "--"); - log << "Effective Matrix Q: " << std::endl; - log << Q << std::endl; - - - - //---VARIANT 2 - //Compute effective elastic law Q - MatrixRT Q_2(0); - for(size_t a = 0; a < 3; a++) - for(size_t b=0; b < 3; b++) - { - std::cout << "check_Orthogonality:" << check_Orthogonality(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[b],*phiDerContainer[a],*phiDerContainer[b],x3MatrixBasis[a]) << std::endl; - Q_2[a][b] = computeFullQ(Basis_CE, muLocal, lambdaLocal,gamma,mContainer[a],mContainer[b],*phiDerContainer[a],*phiDerContainer[b],x3MatrixBasis[a],x3MatrixBasis[b]); - } - printmatrix(std::cout, Q_2, "Matrix Q_2", "--"); -// Q = Q_2; - - //--- VARIANT 3 - // Compute effective elastic law Q -// MatrixRT Q_3(0); -// for(size_t a = 0; a < 3; a++) -// for(size_t b=0; b < 3; b++) -// { -// assembleCellLoad(Basis_CE, muLocal, lambdaLocal, gamma, tmp1 ,x3MatrixBasis[b]); // <L i(M_alpha) + sym(grad phi_alpha), i(x3G_beta) > -// -// double GGterm = 0.0; -// GGterm = energy(Basis_CE, muLocal, lambdaLocal, x3MatrixBasis[a] , x3MatrixBasis[b] ); // <L i(x3G_alpha) , i(x3G_beta) > -// -// // TEST -// // std::setprecision(std::numeric_limits<float>::digits10); -// -// Q_3[a][b] = (coeffContainer[a]*tmp1) + GGterm; // seems symmetric...check positiv definitness? -// -// if (print_debug) -// { -// std::cout << "analyticGGTERM:" << (mu1*(1-theta)+mu2*theta)/6.0 << std::endl; -// std::cout << "GGTerm:" << GGterm << std::endl; -// std::cout << "coeff*tmp: " << coeffContainer[a]*tmp1 << std::endl; -// } -// } -// printmatrix(std::cout, Q_3, "Matrix Q_3", "--"); - - - - - // compute B_hat - for(size_t a = 0; a<3; a++) - { - assembleCellLoad(Basis_CE, muLocal, lambdaLocal, gamma, tmp2 ,B_Term); // <L i(M_alpha) + sym(grad phi_alpha), B > - auto GBterm = energy(Basis_CE, muLocal, lambdaLocal, x3MatrixBasis[a] , B_Term); // <L i(x3G_alpha) , B> - B_hat[a] = (coeffContainer[a]*tmp2) + GBterm; - - if (print_debug) - { - std::cout << "check this Contribution: " << (coeffContainer[a]*tmp2) << std::endl; //see orthotropic.tex - } - } - -// log << B_hat << std::endl; -// log << "Prestrain B_hat: " << std::endl; -// log << B_hat << std::endl; - - std::cout << "check this Contribution: " << (coeffContainer[2]*tmp2) << std::endl; //see orthotropic.tex - - /////////////////////////////// - // Compute effective Prestrain B_eff - ////////////////////////////// - FieldVector<double, 3> Beff; - Q.solve(Beff,B_hat); - - log << "--- Prestrain Output --- " << std::endl; - log << "B_hat: " << B_hat << std::endl; - log << "B_eff: " << Beff << " (Effective Prestrain)" << std::endl; - log << "------------------------ " << std::endl; -// log << Beff << std::endl; -// log << "Effective Prestrain B_eff: " << std::endl; -// log << Beff << std::endl; -// printvector(std::cout, Beff, "Beff", "--"); - - auto q1 = Q[0][0]; - auto q2 = Q[1][1]; - auto q3 = Q[2][2]; - -// std::cout<< "q1 : " << q1 << std::endl; -// std::cout<< "q2 : " << q2 << std::endl; - std::cout.precision(10); -// std::cout << "q3 : " << std::fixed << q3 << std::endl; -// std::cout<< "q3 : " << q3 << std::endl; - std::cout<< std::fixed << std::setprecision(6) << "q_onetwo=" << Q[0][1] << std::endl; -// std::cout<< std::fixed << std::setprecision(6) << "q_onetwo=" << Q[1][0] << std::endl; //TEST - printvector(std::cout, B_hat, "B_hat", "--"); - printvector(std::cout, Beff, "Beff", "--"); - - std::cout << "Theta: " << theta << std::endl; - std::cout << "Gamma: " << gamma << std::endl; - std::cout << "Number of Elements in each direction: " << nElements << std::endl; - log << "q1=" << q1 << std::endl; - log << "q2=" << q2 << std::endl; - log << "q3=" << q3 << std::endl; - log << "q12=" << Q[0][1] << std::endl; - - log << "b1=" << Beff[0] << std::endl; - log << "b2=" << Beff[1] << std::endl; - log << "b3=" << Beff[2] << std::endl; - log << "b1_hat: " << B_hat[0] << std::endl; - log << "b2_hat: " << B_hat[1] << std::endl; - log << "b3_hat: " << B_hat[2] << std::endl; - log << "mu_gamma=" << q3 << std::endl; // added for Python-Script - - log << std::fixed << std::setprecision(6) << "q_onetwo=" << Q[0][1] << std::endl; -// log << "q_onetwo=" << Q[0][1] << std::endl; // added for Python-Script - - ////////////////////////////////////////////////////////////// - // Define Analytic Solutions - ////////////////////////////////////////////////////////////// - - - - - - - std::cout << "Test B_hat & B_eff" << std::endl; - double p1 = parameterSet.get<double>("rho1", 1.0); - double alpha = parameterSet.get<double>("alpha", 2.0); - double p2 = alpha*p1; - - if (imp == "parametrized_Laminate" && lambda1==0 ) // only in this case we know an analytical solution - { - double rho1 = parameterSet.get<double>("rho1", 1.0); -// double b1_hat_ana = (-(theta/4.0)*mu1*mu2)/(theta*mu1+(1.0-theta)*mu2); -// double b2_hat_ana = -(theta/4.0)*mu2; -// double b3_hat_ana = 0.0; - - double b1_eff_ana = (3.0/2.0)*rho1*(1-theta*(1+alpha)); - double b2_eff_ana = (3.0/2.0)*rho1*((1-theta*(1+beta*alpha))/(1-theta+theta*beta)); - double b3_eff_ana = 0.0; - - // double q1_ana = ((mu1*mu2)/6.0)/(theta*mu1+ (1.0- theta)*mu2); - // double q2_ana = ((1.0-theta)*mu1+theta*mu2)/6.0; - double q1_ana = mu1*(beta/(theta+(1-theta)*beta)) *(1.0/6.0); // 1/6 * harmonicMean - double q2_ana = mu1*((1-theta)+theta*beta) *(1.0/6.0); // 1/6 * arithmeticMean - - std::cout << "----- print analytic solutions -----" << std::endl; -// std::cout << "b1_hat_ana : " << b1_hat_ana << std::endl; -// std::cout << "b2_hat_ana : " << b2_hat_ana << std::endl; -// std::cout << "b3_hat_ana : " << b3_hat_ana << std::endl; - std::cout << "b1_eff_ana : " << b1_eff_ana << std::endl; - std::cout << "b2_eff_ana : " << b2_eff_ana << std::endl; - std::cout << "b3_eff_ana : " << b3_eff_ana << std::endl; - - std::cout << "q1_ana : " << q1_ana << std::endl; - std::cout << "q2_ana : " << q2_ana << std::endl; - std::cout << "q3 should be between q1 and q2" << std::endl; - log << "----- print analytic solutions -----" << std::endl; -// log << "b1_hat_ana : " << b1_hat_ana << std::endl; -// log << "b2_hat_ana : " << b2_hat_ana << std::endl; -// log << "b3_hat_ana : " << b3_hat_ana << std::endl; - log << "b1_eff_ana : " << b1_eff_ana << std::endl; - log << "b2_eff_ana : " << b2_eff_ana << std::endl; - log << "b3_eff_ana : " << b3_eff_ana << std::endl; - log << "q1_ana : " << q1_ana << std::endl; - log << "q2_ana : " << q2_ana << std::endl; - log << "q3 should be between q1 and q2" << std::endl; - - Storage_Quantities.push_back(std::abs(q1_ana - q1)); - Storage_Quantities.push_back(std::abs(q2_ana - q2)); - Storage_Quantities.push_back(q3); - Storage_Quantities.push_back(std::abs(b1_eff_ana - Beff[0])); - Storage_Quantities.push_back(std::abs(b2_eff_ana - Beff[1])); - Storage_Quantities.push_back(std::abs(b3_eff_ana - Beff[2])); - } - else if (imp == "analytical_Example") // print Errors only for analytical_Example - { - std::cout << ((3.0*p1)/2.0)*beta*(1-(theta*(1+alpha))) << std::endl; // TODO ERROR in paper ?? - - // double b1 = (mu1*p1/4)*(beta/(theta+(1-theta)*beta))*(1-theta*(1+alpha)); - // double b2 = (mu1*p1/8)*(1-theta*(1+beta*alpha)); - double b1_hat_ana = (-(theta/4.0)*mu1*mu2)/(theta*mu1+(1.0-theta)*mu2); - double b2_hat_ana = -(theta/4.0)*mu2; - double b3_hat_ana = 0.0; - - double b1_eff_ana = (-3.0/2.0)*theta; - double b2_eff_ana = (-3.0/2.0)*(theta*mu2)/(mu1*(1-theta)+mu2*theta); - double b3_eff_ana = 0.0; - - // double q1_ana = ((mu1*mu2)/6.0)/(theta*mu1+ (1.0- theta)*mu2); - // double q2_ana = ((1.0-theta)*mu1+theta*mu2)/6.0; - double q1_ana = mu1*(beta/(theta+(1-theta)*beta)) *(1.0/6.0); // 1/6 * harmonicMean - double q2_ana = mu1*((1-theta)+theta*beta) *(1.0/6.0); // 1/6 * arithmeticMean - - std::cout << "----- print analytic solutions -----" << std::endl; - std::cout << "b1_hat_ana : " << b1_hat_ana << std::endl; - std::cout << "b2_hat_ana : " << b2_hat_ana << std::endl; - std::cout << "b3_hat_ana : " << b3_hat_ana << std::endl; - std::cout << "b1_eff_ana : " << b1_eff_ana << std::endl; - std::cout << "b2_eff_ana : " << b2_eff_ana << std::endl; - std::cout << "b3_eff_ana : " << b3_eff_ana << std::endl; - - std::cout << "q1_ana : " << q1_ana << std::endl; - std::cout << "q2_ana : " << q2_ana << std::endl; - std::cout << "q3 should be between q1 and q2" << std::endl; - log << "----- print analytic solutions -----" << std::endl; - log << "b1_hat_ana : " << b1_hat_ana << std::endl; - log << "b2_hat_ana : " << b2_hat_ana << std::endl; - log << "b3_hat_ana : " << b3_hat_ana << std::endl; - log << "b1_eff_ana : " << b1_eff_ana << std::endl; - log << "b2_eff_ana : " << b2_eff_ana << std::endl; - log << "b3_eff_ana : " << b3_eff_ana << std::endl; - log << "q1_ana : " << q1_ana << std::endl; - log << "q2_ana : " << q2_ana << std::endl; - log << "q3 should be between q1 and q2" << std::endl; - - Storage_Quantities.push_back(std::abs(q1_ana - q1)); - Storage_Quantities.push_back(std::abs(q2_ana - q2)); - Storage_Quantities.push_back(q3); - Storage_Quantities.push_back(std::abs(b1_eff_ana - Beff[0])); - Storage_Quantities.push_back(std::abs(b2_eff_ana - Beff[1])); - Storage_Quantities.push_back(std::abs(b3_eff_ana - Beff[2])); - } - else - { - Storage_Quantities.push_back(q1); - Storage_Quantities.push_back(q2); - Storage_Quantities.push_back(q3); - Storage_Quantities.push_back(Beff[0]); - Storage_Quantities.push_back(Beff[1]); - Storage_Quantities.push_back(Beff[2]); - } - - - auto symPhi_1_analytic = [mu1, mu2, theta, muTerm] (const Domain& x) { - return MatrixRT{{ (((mu1*mu2)/((theta*mu1 +(1-theta)*mu2)*muTerm(x))) - 1)*x[2] , 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - - - if(write_L2Error) - { - -// std::cout << " ----- L2ErrorSym ----" << std::endl; - auto L2SymError = computeL2SymError(Basis_CE,phi_1,gamma,symPhi_1_analytic); -// std::cout << "L2SymError: " << L2SymError << std::endl; -// std::cout << " -----------------" << std::endl; - -// std::cout << " ----- L2NORMSym ----" << std::endl; - auto L2Norm_Symphi = computeL2SymError(Basis_CE,phi_1,gamma,zeroFunction); -// std::cout << "L2-Norm(Symphi_1): " << L2Norm_Symphi << std::endl; - VectorCT zeroVec; - zeroVec.resize(Basis_CE.size()); - zeroVec = 0; - auto L2Norm_SymAnalytic = computeL2SymError(Basis_CE,zeroVec ,gamma, symPhi_1_analytic); -// std::cout << "L2-Norm(SymAnalytic): " << L2Norm_SymAnalytic << std::endl; -// std::cout << " -----------------" << std::endl; - -// std::cout << " ----- L2NORM ----" << std::endl; - auto L2Norm = computeL2Norm(Basis_CE,phi_1); -// std::cout << "L2Norm(phi_1): " << L2Norm << std::endl; -// std::cout << " -----------------" << std::endl; - - - -// log << "L2-Error (symmetric Gradient phi_1):" << L2SymError << std::endl; -// log << "L2-Norm(Symphi_1): " << L2Norm_Symphi<< std::endl; -// log << "L2-Norm(SymAnalytic): " << L2Norm_SymAnalytic << std::endl; - - double EOC = 0.0; - Storage_Error.push_back(L2SymError); - - //Compute Experimental order of convergence (EOC) - if(levelCounter > 0) - { - // Storage_Error:: #1 level #2 L2SymError #3 L2SymErrorOrder #4 L2Norm(sym) #5 L2Norm(sym-analytic) #6 L2Norm(phi_1) -// std::cout << " ((levelCounter-1)*6)+1: " << ((levelCounter-1)*6)+1 << std::endl; // Besser std::map ??? -// std::cout << " ((levelCounter-1)*6)+1: " << ((levelCounter)*6)+1 << std::endl; // für Storage_Error[idx] muss idx zur compile time feststehen?! - auto ErrorOld = std::get<double>(Storage_Error[((levelCounter-1)*6)+1]); - auto ErrorNew = std::get<double>(Storage_Error[(levelCounter*6)+1]); -// - EOC = std::log(ErrorNew/ErrorOld)/(-1*std::log(2)); - // std::cout << "Storage_Error[0] :" << std::get<1>(Storage_Error[0]) << std::endl; - // std::cout << "output variant :" << std::get<std::string>(Storage_Error[1]) << std::endl; - // std::cout << "output variant :" << std::get<0>(Storage_Error[1]) << std::endl; - } -// Storage_Error.push_back(level); - Storage_Error.push_back(EOC); - Storage_Error.push_back(L2Norm_Symphi); - Storage_Error.push_back(L2Norm_SymAnalytic); - Storage_Error.push_back(L2Norm); - } - ////////////////////////////////////////////////////////////////////////////////////////////// - // Write Data to Matlab / Optimization-Code - ////////////////////////////////////////////////////////////////////////////////////////////// -// writeMatrixToMatlab(Q, "../../Matlab-Programs/QMatrix.txt"); - writeMatrixToMatlab(Q, outputPath + "/QMatrix.txt"); - - // write effective Prestrain in Matrix for Output - FieldMatrix<double,1,3> BeffMat; - BeffMat[0] = Beff; -// writeMatrixToMatlab(BeffMat, "../../Matlab-Programs/BMatrix.txt"); - writeMatrixToMatlab(BeffMat, outputPath + "/BMatrix.txt"); - - ////////////////////////////////////////////////////////////////////////////////////////////// - // Write result to VTK file - ////////////////////////////////////////////////////////////////////////////////////////////// - if(write_VTK) - { - std::string vtkOutputName = outputPath + "/CellProblem-result"; - - std::cout << "vtkOutputName:" << vtkOutputName << std::endl; - - VTKWriter<GridView> vtkWriter(gridView_CE); - - vtkWriter.addVertexData( - correctorFunction_1, - VTK::FieldInfo("Corrector phi_1 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - correctorFunction_2, - VTK::FieldInfo("Corrector phi_2 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - correctorFunction_3, - VTK::FieldInfo("Corrector phi_3 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - // vtkWriter.write( vtkOutputName ); - vtkWriter.write(vtkOutputName + "-level"+ std::to_string(level)); - // vtkWriter.pwrite( vtkOutputName + "-level"+ std::to_string(level), outputPath, ""); // TEST Write to folder "/outputs" - // vtkWriter.pwrite( vtkOutputName + "-level"+ std::to_string(level), outputPath, "", VTK::OutputType::ascii, 0, 0 ); - std::cout << "wrote data to file: " + vtkOutputName + "-level" + std::to_string(level) << std::endl; - } - - - if (write_materialFunctions) - { - using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); - VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); - - using GridViewVTK = VTKGridType::LeafGridView; - const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - - auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); - auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - - std::vector<double> mu_CoeffP0; - Functions::interpolate(scalarP0FeBasis, mu_CoeffP0, muTerm); - auto mu_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, mu_CoeffP0); - - std::vector<double> mu_CoeffP1; - Functions::interpolate(scalarP1FeBasis, mu_CoeffP1, muTerm); - auto mu_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, mu_CoeffP1); - - - std::vector<double> lambda_CoeffP0; - Functions::interpolate(scalarP0FeBasis, lambda_CoeffP0, lambdaTerm); - auto lambda_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, lambda_CoeffP0); - - std::vector<double> lambda_CoeffP1; - Functions::interpolate(scalarP1FeBasis, lambda_CoeffP1, lambdaTerm); - auto lambda_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, lambda_CoeffP1); - - VTKWriter<GridView> MaterialVtkWriter(gridView_VTK); - - MaterialVtkWriter.addVertexData( - mu_DGBF_P1, - VTK::FieldInfo("mu_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - mu_DGBF_P0, - VTK::FieldInfo("mu_P0", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addVertexData( - lambda_DGBF_P1, - VTK::FieldInfo("lambda_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - lambda_DGBF_P0, - VTK::FieldInfo("lambda_P0", VTK::FieldInfo::Type::scalar, 1)); - - MaterialVtkWriter.write(outputPath + "/MaterialFunctions-level"+ std::to_string(level) ); - std::cout << "wrote data to file:" + outputPath +"/MaterialFunctions-level" + std::to_string(level) << std::endl; - - } - - if (write_prestrainFunctions) - { - using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); - VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); - using GridViewVTK = VTKGridType::LeafGridView; - const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - - FTKfillerContainer<dim> VTKFiller; - VTKFiller.vtkPrestrainNorm(gridView_VTK, B_Term, "PrestrainBNorm"); - - // WORKS Too - VTKFiller.vtkProblemCell(gridView_VTK, B_Term, muLocal,"VTKProblemCell");; - - - // TEST - auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); - auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - - std::vector<double> B_CoeffP0; - Functions::interpolate(scalarP0FeBasis, B_CoeffP0, B_Term); - auto B_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, B_CoeffP0); - - - - VTKWriter<GridView> PrestrainVtkWriter(gridView_VTK); - - PrestrainVtkWriter.addCellData( - B_DGBF_P0, - VTK::FieldInfo("B_P0", VTK::FieldInfo::Type::scalar, 1)); - - PrestrainVtkWriter.write(outputPath + "/PrestrainFunctions-level"+ std::to_string(level) ); - std::cout << "wrote data to file:" + outputPath +"/PrestrainFunctions-level" + std::to_string(level) << std::endl; - - } - - - levelCounter++; - } // Level-Loop End - - - - - ///////////////////////////////////////// - // Print Storage - ///////////////////////////////////////// - int tableWidth = 12; - if (imp == "analytical_Example") // print Errors only for analytical_Example - { - std::cout << std::string(tableWidth*7 + 3*7, '-') << "\n"; - std::cout << center("Levels",tableWidth) << " | " - << center("L2SymError",tableWidth) << " | " - << center("Order",tableWidth) << " | " - << center("L2SymNorm",tableWidth) << " | " - << center("L2SymNorm_ana",tableWidth) << " | " - << center("L2Norm",tableWidth) << " | " << "\n"; - std::cout << std::string(tableWidth*6 + 3*6, '-') << "\n"; - log << std::string(tableWidth*6 + 3*6, '-') << "\n"; - log << center("Levels",tableWidth) << " | " - << center("L2SymError",tableWidth) << " | " - << center("Order",tableWidth) << " | " - << center("L2SymNorm",tableWidth) << " | " - << center("L2SNorm_ana",tableWidth) << " | " - << center("L2Norm",tableWidth) << " | " << "\n"; - log << std::string(tableWidth*6 + 3*6, '-') << "\n"; - - int StorageCount = 0; - - for(auto& v: Storage_Error) - { - std::visit([tableWidth](auto&& arg){std::cout << center(prd(arg,5,1),tableWidth) << " | ";}, v); // Anzahl-Nachkommastellen - std::visit([tableWidth, &log](auto&& arg){log << center(prd(arg,5,1),tableWidth) << " & ";}, v); - StorageCount++; - if(StorageCount % 6 == 0 ) - { - std::cout << std::endl; - log << std::endl; - } - } - } - - //////////////// OUTPUT QUANTITIES TABLE ////////////// - if (imp == "analytical_Example" || (imp == "parametrized_Laminate" && lambda1==0 ) ) // print Errors only for analytical_Example - { - std::cout << std::string(tableWidth*7 + 3*7, '-') << "\n"; - std::cout << center("Levels ",tableWidth) << " | " - << center("|q1_ana-q1|",tableWidth) << " | " - << center("|q2_ana-q2|",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("|b1_ana-b1|",tableWidth) << " | " - << center("|b2_ana-b2|",tableWidth) << " | " - << center("|b3_ana-b3|",tableWidth) << " | " << "\n"; - std::cout << std::string(tableWidth*7 + 3*7, '-') << "\n"; - log << std::string(tableWidth*7 + 3*7, '-') << "\n"; - log << center("Levels ",tableWidth) << " | " - << center("|q1_ana-q1|",tableWidth) << " | " - << center("|q2_ana-q2|",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("|b1_ana-b1|",tableWidth) << " | " - << center("|b2_ana-b2|",tableWidth) << " | " - << center("|b3_ana-b3|",tableWidth) << " | " << "\n"; - log << std::string(tableWidth*7 + 3*7, '-') << "\n"; - } - else - { - std::cout << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - std::cout << std::string(tableWidth*7 + 3*7, '-') << "\n"; - log << std::string(tableWidth*7 + 3*7, '-') << "\n"; - log << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - log << std::string(tableWidth*7 + 3*7, '-') << "\n"; - } - - int StorageCount2 = 0; - for(auto& v: Storage_Quantities) - { - std::visit([tableWidth](auto&& arg){std::cout << center(prd(arg,5,1),tableWidth) << " | ";}, v); - std::visit([tableWidth, &log](auto&& arg){log << center(prd(arg,5,1),tableWidth) << " & ";}, v); - StorageCount2++; - if(StorageCount2 % 7 == 0 ) - { - std::cout << std::endl; - log << std::endl; - } - } - std::cout << std::string(tableWidth*7 + 3*7, '-') << "\n"; - log << std::string(tableWidth*7 + 3*7, '-') << "\n"; - - log.close(); - - std::cout << "Total time elapsed: " << globalTimer.elapsed() << std::endl; -} diff --git a/src/deprecated_code/30-8-22_TestingFiles-Comments/CorrectorComputer.hh b/src/deprecated_code/30-8-22_TestingFiles-Comments/CorrectorComputer.hh deleted file mode 100644 index 762125683373d21057d427b7c73397f7168da99e..0000000000000000000000000000000000000000 --- a/src/deprecated_code/30-8-22_TestingFiles-Comments/CorrectorComputer.hh +++ /dev/null @@ -1,1445 +0,0 @@ -#ifndef DUNE_MICROSTRUCTURE_CORRECTORCOMPUTER_HH -#define DUNE_MICROSTRUCTURE_CORRECTORCOMPUTER_HH - -#include <dune/common/parametertree.hh> -#include <dune/common/float_cmp.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/functions/functionspacebases/interpolate.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/microstructure/matrix_operations.hh> - -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number -#include <dune/solvers/solvers/umfpacksolver.hh> - -using namespace Dune; -// using namespace Functions; -using namespace MatrixOperations; - -using std::shared_ptr; -using std::make_shared; -using std::fstream; - - -template <class Basis, class Material> //, class LocalScalar, class Local2Tensor> // LocalFunction derived from basis? -class CorrectorComputer { - -public: - static const int dimworld = 3; //GridView::dimensionworld; - static const int dim = Basis::GridView::dimension; //const int dim = Domain::dimension; - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - - using ScalarRT = FieldVector< double, 1>; - using VectorRT = FieldVector< double, dimworld>; - using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - using FuncScalar = std::function< ScalarRT(const Domain&) >; - using FuncVector = std::function< VectorRT(const Domain&) >; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - using Func2int = std::function< int(const Domain&) >; - - using VectorCT = BlockVector<FieldVector<double,1> >; - using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - using ElementMatrixCT = Matrix<FieldMatrix<double,1,1> >; - - using HierarchicVectorView = Dune::Functions::HierarchicVectorWrapper< VectorCT, double>; - -protected: -//private: - const Basis& basis_; - - - const Material& material_; - - fstream& log_; // Output-log - const ParameterTree& parameterSet_; - - const FuncScalar mu_; - const FuncScalar lambda_; - double gamma_; - - MatrixCT stiffnessMatrix_; - VectorCT load_alpha1_,load_alpha2_,load_alpha3_; //right-hand side(load) vectors - - VectorCT x_1_, x_2_, x_3_; // (all) Corrector coefficient vectors - VectorCT phi_1_, phi_2_, phi_3_; // Corrector phi_i coefficient vectors - FieldVector<double,3> m_1_, m_2_, m_3_; // Corrector m_i coefficient vectors - - MatrixRT M1_, M2_, M3_; // (assembled) corrector matrices M_i - const std::array<MatrixRT*, 3 > mContainer = {&M1_ , &M2_, &M3_}; - const std::array<VectorCT, 3> phiContainer = {phi_1_,phi_2_,phi_3_}; - - // ---- Basis for R_sym^{2x2} - MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - MatrixRT G2_ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0, 0.0, 0.0}}; - MatrixRT G3_ {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > MatrixBasisContainer_ = {G1_, G2_, G3_}; - - Func2Tensor x3G_1_ = [] (const Domain& x) { - return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - }; - - Func2Tensor x3G_2_ = [] (const Domain& x) { - return MatrixRT{{0.0, 0.0, 0.0}, {0.0, 1.0*x[2], 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_3_ = [] (const Domain& x) { - return MatrixRT{{0.0, (1.0/sqrt(2.0))*x[2], 0.0}, {(1.0/sqrt(2.0))*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - const std::array<Func2Tensor, 3> x3MatrixBasisContainer_ = {x3G_1_, x3G_2_, x3G_3_}; - - // --- Offset between basis indices - const int phiOffset_; - -public: - /////////////////////////////// - // constructor - /////////////////////////////// - CorrectorComputer( const Basis& basis, - const Material& material, - const FuncScalar& mu, - const FuncScalar& lambda, - double gamma, - std::fstream& log, - const ParameterTree& parameterSet) - : basis_(basis), - material_(material), - mu_(mu), - lambda_(lambda), - gamma_(gamma), - log_(log), - parameterSet_(parameterSet), - phiOffset_(basis.size()) - { - - assemble(); - - // if (parameterSet.get<bool>("stiffnessmatrix_cellproblem_to_csv")) - // csvSystemMatrix(); - // if (parameterSet.get<bool>("rhs_cellproblem_to_csv")) - // csvRHSs(); - // if (parameterSet.get<bool>("rhs_cellproblem_to_vtk")) - // vtkLoads(); - } - - - // ----------------------------------------------------------------- - // --- Assemble Corrector problems - void assemble() - { - Dune::Timer StiffnessTimer; - assembleCellStiffness(stiffnessMatrix_); - std::cout << "Stiffness assembly Timer: " << StiffnessTimer.elapsed() << std::endl; - - assembleCellLoad(load_alpha1_ ,x3G_1_); - assembleCellLoad(load_alpha2_ ,x3G_2_); - assembleCellLoad(load_alpha3_ ,x3G_3_); - }; - - - - /////////////////////////////// - // getter - /////////////////////////////// - const shared_ptr<Basis> getBasis() {return make_shared<Basis>(basis_);} - - ParameterTree getParameterSet() const {return parameterSet_;} - - fstream* getLog(){return &log_;} - - double getGamma(){return gamma_;} - - shared_ptr<MatrixCT> getStiffnessMatrix(){return make_shared<MatrixCT>(stiffnessMatrix_);} - shared_ptr<VectorCT> getLoad_alpha1(){return make_shared<VectorCT>(load_alpha1_);} - shared_ptr<VectorCT> getLoad_alpha2(){return make_shared<VectorCT>(load_alpha2_);} - shared_ptr<VectorCT> getLoad_alpha3(){return make_shared<VectorCT>(load_alpha3_);} - - shared_ptr<FuncScalar> getMu(){return make_shared<FuncScalar>(mu_);} - shared_ptr<FuncScalar> getLambda(){return make_shared<FuncScalar>(lambda_);} - - shared_ptr<Material> getMaterial(){return make_shared<Material>(material_);} - - // --- Get Correctors - // shared_ptr<VectorCT> getMcontainer(){return make_shared<VectorCT>(mContainer);} - // auto getMcontainer(){return make_shared<std::array<MatrixRT*, 3 > >(mContainer);} - auto getMcontainer(){return mContainer;} - shared_ptr<std::array<VectorCT, 3>> getPhicontainer(){return make_shared<std::array<VectorCT, 3>>(phiContainer);} - - - // shared_ptr<std::array<VectorRT, 3>> getBasiscontainer(){return make_shared<std::array<VectorRT, 3>>(basisContainer_);} - auto getMatrixBasiscontainer(){return make_shared<std::array<MatrixRT,3 >>(MatrixBasisContainer_);} - // auto getx3MatrixBasiscontainer(){return make_shared<std::array<Func2Tensor, 3>>(x3MatrixBasisContainer_);} - auto getx3MatrixBasiscontainer(){return x3MatrixBasisContainer_;} - - - - - - // shared_ptr<VectorCT> getCorr_a(){return make_shared<VectorCT>(x_a_);} - shared_ptr<VectorCT> getCorr_phi1(){return make_shared<VectorCT>(phi_1_);} - shared_ptr<VectorCT> getCorr_phi2(){return make_shared<VectorCT>(phi_2_);} - shared_ptr<VectorCT> getCorr_phi3(){return make_shared<VectorCT>(phi_3_);} - - - - - // Get the occupation pattern of the stiffness matrix - void getOccupationPattern(MatrixIndexSet& nb) - { - // OccupationPattern: - // | phi*phi m*phi | - // | phi *m m*m | - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - nb.resize(basis_.size()+3, basis_.size()+3); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - for (size_t i=0; i<localView.size(); i++) - { - // The global index of the i-th vertex of the element - auto row = localView.index(i); - for (size_t j=0; j<localView.size(); j++ ) - { - // The global index of the j-th vertex of the element - auto col = localView.index(j); - nb.add(row[0],col[0]); // nun würde auch nb.add(row,col) gehen.. - } - } - for (size_t i=0; i<localView.size(); i++) - { - auto row = localView.index(i); - - for (size_t j=0; j<3; j++ ) - { - nb.add(row,phiOffset+j); // m*phi part of StiffnessMatrix - nb.add(phiOffset+j,row); // phi*m part of StiffnessMatrix - } - } - for (size_t i=0; i<3; i++ ) - for (size_t j=0; j<3; j++ ) - { - nb.add(phiOffset+i,phiOffset+j); // m*m part of StiffnessMatrix - } - } - ////////////////////////////////////////////////////////////////// - // setOneBaseFunctionToZero - ////////////////////////////////////////////////////////////////// - if(parameterSet_.get<bool>("set_oneBasisFunction_Zero ", true)){ - FieldVector<int,3> row; - unsigned int arbitraryLeafIndex = parameterSet_.get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet_.get<unsigned int>("arbitraryElementNumber", 0); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); // macht keinen Unterschied ob hier k oder 0.. - const auto nSf = localFiniteElement.localBasis().size(); - assert(arbitraryLeafIndex < nSf ); - assert(arbitraryElementNumber < basis_.gridView().size(0)); // "arbitraryElementNumber larger than total Number of Elements" - - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - row = arbitraryComponentwiseIndices(arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<3; k++) - nb.add(row[k],row[k]); - } - std::cout << "finished occupation pattern\n"; - } - - - template<class localFunction1, class localFunction2> - void computeElementStiffnessMatrix(const typename Basis::LocalView& localView, - ElementMatrixCT& elementMatrix, - const localFunction1& mu, - const localFunction2& lambda - ) - { - // Local StiffnessMatrix of the form: - // | phi*phi m*phi | - // | phi *m m*m | - auto element = localView.element(); - auto geometry = element.geometry(); - // using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - elementMatrix.setSize(localView.size()+3, localView.size()+3); //extend by dim ´R_sym^{2x2} - elementMatrix = 0; - - - auto elasticityTensor = material_.getElasticityTensor(); - // auto indicatorFunction = material_.getIndicatorFunction(); - auto localIndicatorFunction = material_.getLocalIndicatorFunction(); - localIndicatorFunction.bind(element); - // auto indicatorFunctionGVF = material_.getIndicatorFunctionGVF(); - // auto indicatorFunction = localFunction(indicatorFunctionGVF); - // indicatorFunction.bind(element); - // Func2int indicatorFunction = *material_.getIndicatorFunction(); - - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - // std::cout << "localView.size(): " << localView.size() << std::endl; - // std::cout << "nSf : " << nSf << std::endl; - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} // wird nicht als Funktion benötigt da konstant... - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - // double elementContribution = 0.0; - - // std::cout << "Print QuadratureOrder:" << orderQR << std::endl; //TEST` - - int QPcounter= 0; - for (const auto& quadPoint : quad) - { - QPcounter++; - const auto& quadPos = quadPoint.position(); - const auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(quadPos); - const auto integrationElement = geometry.integrationElement(quadPos); - - std::vector< FieldMatrix< double, 1, dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, - referenceGradients); - // Compute the shape function gradients on the grid element - std::vector<FieldVector<double,dim> > gradients(referenceGradients.size()); - - for (size_t i=0; i<gradients.size(); i++) - jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]); - - for (size_t l=0; l< dimworld; l++) - for (size_t j=0; j < nSf; j++ ) - { - size_t row = localView.tree().child(l).localIndex(j); - // (scaled) Deformation gradient of the test basis function - MatrixRT defGradientV(0); - defGradientV[l][0] = gradients[j][0]; // Y - defGradientV[l][1] = gradients[j][1]; //X2 - // defGradientV[l][2] = (1.0/gamma)*gradients[j][2]; //X3 - defGradientV[l][2] = gradients[j][2]; //X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma_),defGradientV); - // "phi*phi"-part - for (size_t k=0; k < dimworld; k++) - for (size_t i=0; i < nSf; i++) - { - // (scaled) Deformation gradient of the ansatz basis function - MatrixRT defGradientU(0); - defGradientU[k][0] = gradients[i][0]; // Y - defGradientU[k][1] = gradients[i][1]; //X2 - // defGradientU[k][2] = (1.0/gamma)*gradients[i][2]; //X3 - defGradientU[k][2] = gradients[i][2]; //X3 - // printmatrix(std::cout, defGradientU , "defGradientU", "--"); - defGradientU = crossSectionDirectionScaling((1.0/gamma_),defGradientU); - - - // auto etmp = material_.applyElasticityTensor(defGradientU,element.geometry().global(quadPos)); - // auto etmp = elasticityTensor(defGradientU,element.geometry().global(quadPos)); - // auto etmp = material_.applyElasticityTensorLocal(defGradientU,quadPos); - // printmatrix(std::cout, etmp, "etmp", "--"); - // double energyDensity= scalarProduct(etmp,defGradientV); - // double energyDensity= scalarProduct(material_.applyElasticityTensor(defGradientU,element.geometry().global(quadPos)),defGradientV); - - // auto tmp_1 = scalarProduct(elasticityTensor(defGradientU,indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)); - // auto tmp_2 = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); - // if (abs(tmp_1-tmp_2)>1e-2) - // { - // std::cout << "difference :" << abs(tmp_1-tmp_2) << std::endl; - // std::cout << "scalarProduct(elasticityTensor(defGradientU,indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV))" << scalarProduct(elasticityTensor(defGradientU,indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV))<< std::endl; - // std::cout << "linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV)" << linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV)<< std::endl; - // } - - - // Python::Module module = Python::import("material_neukamm"); - // auto PythonindicatorFunction = Python::make_function<int>(module.get("f")); - // if (PythonindicatorFunction(element.geometry().global(quadPos)) != material_.applyIndicatorFunction(element.geometry().global(quadPos))) - // { - // std::cout <<" element.geometry().global(quadPos): " << element.geometry().global(quadPos) << std::endl; - // std::cout << "PythonindicatorFunction(element.geometry().global(quadPos)): " << PythonindicatorFunction(element.geometry().global(quadPos)) << std::endl; - // // std::cout << "mu(quadPos):" << mu(quadPos) << std::endl; - // std::cout << "indicatorFunction(element.geometry().global(quadPos)): " << indicatorFunction(element.geometry().global(quadPos)) << std::endl; - // std::cout << "material_.applyIndicatorFunction(element.geometry().global(quadPos)): " << material_.applyIndicatorFunction(element.geometry().global(quadPos)) << std::endl; - // std::cout << "indicatorFunction_material_1: " << indicatorFunction_material_1(element.geometry().global(quadPos)) << std::endl; - // } - // double energyDensity= scalarProduct(material_.ElasticityTensorGlobal(defGradientU,element.geometry().global(quadPos)),sym(defGradientV)); - double energyDensity= scalarProduct(material_.ElasticityTensor(defGradientU,localIndicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor(defGradientU,localIndicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor(defGradientU,indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor(defGradientU,indicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensor(defGradientU,element.geometry().global(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.localElasticityTensor(defGradientU,quadPos,element),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensor(defGradientU,quadPos),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensorLocal(defGradientU,quadPos),defGradientV); - - - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), defGradientU, defGradientV); //TEST - // double energyDensity = generalizedDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); // also works.. - - size_t col = localView.tree().child(k).localIndex(i); - - elementMatrix[row][col] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "m*phi" & "phi*m" - part - for( size_t m=0; m<3; m++) - { - - - // auto tmp_1 = scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)) ; - // auto tmp_2 = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV); - // if (abs(tmp_1-tmp_2)>1e-2) - // { - // std::cout << "difference :" << abs(tmp_1-tmp_2) << std::endl; - // std::cout << "scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)) " << scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)) << std::endl; - // std::cout << "linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV)" << linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV) << std::endl; - // } - - - // double energyDensityGphi = scalarProduct(material_.ElasticityTensorGlobal(basisContainer[m],element.geometry().global(quadPos)),sym(defGradientV)); - double energyDensityGphi = scalarProduct(material_.ElasticityTensor(basisContainer[m],localIndicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(elasticityTensor(basisContainer[m],localIndicatorFunction(quadPos)),sym(defGradientV)); - // std::cout << "scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV))" << scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)) <<std::endl; - // std::cout << "linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV)" << linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV) << std::endl; - // double energyDensityGphi= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),defGradientV); - // double energyDensityGphi= scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(material_.applyElasticityTensor(basisContainer[m],quadPos),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(material_.localElasticityTensor(basisContainer[m],quadPos,element),sym(defGradientV)); - // double energyDensityGphi= scalarProduct(elasticityTensor(basisContainer[m],element.geometry().global(quadPos)),defGradientV); - // double energyDensityGphi= scalarProduct(material_.applyElasticityTensorLocal(basisContainer[m],quadPos),defGradientV); - // double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV); - // double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], defGradientV); //TEST - auto value = energyDensityGphi * quadPoint.weight() * integrationElement; - elementMatrix[row][localPhiOffset+m] += value; - elementMatrix[localPhiOffset+m][row] += value; - } - - } - // "m*m"-part - for(size_t m=0; m<3; m++) //TODO ist symmetric.. reicht die hälfte zu berechnen!!! - for(size_t n=0; n<3; n++) - { - - // std::cout << "QPcounter: " << QPcounter << std::endl; - // std::cout << "m= " << m << " n = " << n << std::endl; - // printmatrix(std::cout, basisContainer[m] , "basisContainer[m]", "--"); - // printmatrix(std::cout, basisContainer[n] , "basisContainer[n]", "--"); - // std::cout << "integrationElement:" << integrationElement << std::endl; - // std::cout << "quadPoint.weight(): "<< quadPoint.weight() << std::endl; - // std::cout << "mu(quadPos): " << mu(quadPos) << std::endl; - // std::cout << "lambda(quadPos): " << lambda(quadPos) << std::endl; - - // auto tmp_1 = scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(basisContainer[n])); - // auto tmp_2 = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n]); - // if (abs(tmp_1-tmp_2)>1e-2) - // { - // std::cout << "difference :" << abs(tmp_1-tmp_2) << std::endl; - // std::cout << "scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(basisContainer[n])):" << scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(basisContainer[n])) << std::endl; - // std::cout << "linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n])" << linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n])<< std::endl; - - // } - // double energyDensityGG = scalarProduct(material_.ElasticityTensorGlobal(basisContainer[m],element.geometry().global(quadPos)),sym(basisContainer[n])); - double energyDensityGG = scalarProduct(material_.ElasticityTensor(basisContainer[m],localIndicatorFunction(quadPos)),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(elasticityTensor(basisContainer[m],localIndicatorFunction(quadPos)),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(element.geometry().global(quadPos))),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(elasticityTensor(basisContainer[m],element.geometry().global(quadPos)),basisContainer[n]); - // double energyDensityGG= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),basisContainer[n]); - // double energyDensityGG= scalarProduct(elasticityTensor(basisContainer[m],indicatorFunction(quadPos)),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(material_.applyElasticityTensor(basisContainer[m],quadPos),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(material_.localElasticityTensor(basisContainer[m],quadPos,element),sym(basisContainer[n])); - // double energyDensityGG= scalarProduct(material_.applyElasticityTensorLocal(basisContainer[m],quadPos),basisContainer[n]); - - // double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n]); - // double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], basisContainer[n]); //TEST - elementMatrix[localPhiOffset+m][localPhiOffset+n] += energyDensityGG * quadPoint.weight() * integrationElement; // += !!!!! (Fixed-Bug) - - // std::cout << "energyDensityGG:" << energyDensityGG<< std::endl; - // std::cout << "product " << energyDensityGG * quadPoint.weight() * integrationElement << std::endl; - // printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); - } - } - // std::cout << "Number of QuadPoints:" << QPcounter << std::endl; - // printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); - } - - - - // Compute the source term for a single element - // < L (sym[D_gamma*nabla phi_i] + M_i ), x_3G_alpha > - template<class LocalFunction1, class LocalFunction2, class Vector, class LocalForce> - void computeElementLoadVector( const typename Basis::LocalView& localView, - LocalFunction1& mu, - LocalFunction2& lambda, - Vector& elementRhs, - const LocalForce& forceTerm - ) - { - // | f*phi| - // | --- | - // | f*m | - // using Element = typename LocalView::Element; - const auto element = localView.element(); - const auto geometry = element.geometry(); - // constexpr int dim = Element::dimension; - // constexpr int dimworld = dim; - - // using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - auto elasticityTensor = material_.getElasticityTensor(); - // auto indicatorFunction = material_.getIndicatorFunction(); - auto localIndicatorFunction = material_.getLocalIndicatorFunction(); - localIndicatorFunction.bind(element); - // // auto indicatorFunction = material_.getLocalIndicatorFunction(); - // auto indicatorFunctionGVF = material_.getIndicatorFunctionGVF(); - // auto indicatorFunction = localFunction(indicatorFunctionGVF); - // indicatorFunction.bind(element); - // Func2int indicatorFunction = *material_.getIndicatorFunction(); - - - // Set of shape functions for a single element - const auto& localFiniteElement= localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - elementRhs.resize(localView.size() +3); - elementRhs = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - // std::cout << "Quad-Rule order used: " << orderQR << std::endl; - - for (const auto& quadPoint : quad) - { - const FieldVector<double,dim>& quadPos = quadPoint.position(); - const auto jacobian = geometry.jacobianInverseTransposed(quadPos); - const double integrationElement = geometry.integrationElement(quadPos); - - std::vector<FieldMatrix<double,1,dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients); - - std::vector< FieldVector< double, dim> > gradients(referenceGradients.size()); - for (size_t i=0; i< gradients.size(); i++) - jacobian.mv(referenceGradients[i][0], gradients[i]); - - //TEST - // std::cout << "forceTerm(element.geometry().global(quadPos)):" << std::endl; - // std::cout << forceTerm(element.geometry().global(quadPos)) << std::endl; - // std::cout << "forceTerm(quadPos)" << std::endl; - // std::cout << forceTerm(quadPos) << std::endl; - // - // //TEST QUadrature - // std::cout << "quadPos:" << quadPos << std::endl; - // std::cout << "element.geometry().global(quadPos):" << element.geometry().global(quadPos) << std::endl; - // // // - // // // - // std::cout << "quadPoint.weight() :" << quadPoint.weight() << std::endl; - // std::cout << "integrationElement(quadPos):" << integrationElement << std::endl; - // std::cout << "mu(quadPos) :" << mu(quadPos) << std::endl; - // std::cout << "lambda(quadPos) :" << lambda(quadPos) << std::endl; - - - // "f*phi"-part - for (size_t i=0; i < nSf; i++) - for (size_t k=0; k < dimworld; k++) - { - // Deformation gradient of the ansatz basis function - MatrixRT defGradientV(0); - defGradientV[k][0] = gradients[i][0]; // Y - defGradientV[k][1] = gradients[i][1]; // X2 - // defGradientV[k][2] = (1.0/gamma_)*gradients[i][2]; // - defGradientV[k][2] = gradients[i][2]; // X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma_),defGradientV); - - // double energyDensity= scalarProduct(material_.ElasticityTensorGlobal((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),sym(defGradientV)); - double energyDensity= scalarProduct(material_.ElasticityTensor((-1.0)*forceTerm(quadPos),localIndicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),localIndicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),indicatorFunction(element.geometry().global(quadPos))),sym(defGradientV)); - // double energyDensity= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),indicatorFunction(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.localElasticityTensor((-1.0)*forceTerm(quadPos),quadPos,element),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),quadPos),sym(defGradientV)); - // double energyDensity= scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),defGradientV); - // double energyDensity= scalarProduct(material_.applyElasticityTensorLocal((-1.0)*forceTerm(quadPos),quadPos),defGradientV); - - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),(-1.0)*forceTerm(quadPos), defGradientV ); - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)),forceTerm(quadPos), defGradientV ); //TEST - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),(-1.0)*forceTerm(quadPos), defGradientV ); //TEST - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),forceTerm(element.geometry().global(quadPos)), defGradientV ); //TEST - - size_t row = localView.tree().child(k).localIndex(i); - elementRhs[row] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "f*m"-part - for (size_t m=0; m<3; m++) - { - // double energyDensityfG= scalarProduct(material_.ElasticityTensorGlobal((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),sym(basisContainer[m])); - double energyDensityfG= scalarProduct(material_.ElasticityTensor((-1.0)*forceTerm(quadPos),localIndicatorFunction(quadPos)),sym(basisContainer[m])); - // double energyDensityfG= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),localIndicatorFunction(quadPos)),sym(basisContainer[m])); - // double energyDensityfG= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),indicatorFunction(element.geometry().global(quadPos))),sym(basisContainer[m])); - // double energyDensityfG= scalarProduct(elasticityTensor((-1.0)*forceTerm(quadPos),indicatorFunction(quadPos)),sym(basisContainer[m])); - // double energyDensityfG = scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),sym(basisContainer[m])); - // double energyDensityfG = scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),quadPos),sym(basisContainer[m])); - // double energyDensityfG = scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),basisContainer[m]); - // double energyDensityfG = scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),quadPos),basisContainer[m]); - // double energyDensityfG = scalarProduct(material_.localElasticityTensor((-1.0)*forceTerm(quadPos),quadPos,element),basisContainer[m]); - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), (-1.0)*forceTerm(quadPos),basisContainer[m] ); - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), forceTerm(quadPos),basisContainer[m] ); //TEST - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), (-1.0)*forceTerm(quadPos),basisContainer[m] ); //TEST - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), forceTerm(element.geometry().global(quadPos)),basisContainer[m] );//TEST - elementRhs[localPhiOffset+m] += energyDensityfG * quadPoint.weight() * integrationElement; - // std::cout << "energyDensityfG * quadPoint.weight() * integrationElement: " << energyDensityfG * quadPoint.weight() * integrationElement << std::endl; - } - } - } - - - void assembleCellStiffness(MatrixCT& matrix) - { - std::cout << "assemble Stiffness-Matrix begins." << std::endl; - - MatrixIndexSet occupationPattern; - getOccupationPattern(occupationPattern); - occupationPattern.exportIdx(matrix); - matrix = 0; - - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambdaLocal = localFunction(lambdaGridF); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - const int localPhiOffset = localView.size(); - // Dune::Timer Time; - //std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - Matrix<FieldMatrix<double,1,1> > elementMatrix; - computeElementStiffnessMatrix(localView, elementMatrix, muLocal, lambdaLocal); - - // std::cout << "local assembly time:" << Time.elapsed() << std::endl; - - //printmatrix(std::cout, elementMatrix, "ElementMatrix", "--"); - //std::cout << "elementMatrix.N() : " << elementMatrix.N() << std::endl; - //std::cout << "elementMatrix.M() : " << elementMatrix.M() << std::endl; - - //TEST - //Check Element-Stiffness-Symmetry: - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - if(abs(elementMatrix[i][j] - elementMatrix[j][i]) > 1e-12 ) - std::cout << "ELEMENT-STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL STIFFNES ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - matrix[row][col] += elementMatrix[i][j]; - } - for (size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - matrix[row][phiOffset+m] += elementMatrix[i][localPhiOffset+m]; - matrix[phiOffset+m][row] += elementMatrix[localPhiOffset+m][i]; - } - for (size_t m=0; m<3; m++ ) - for (size_t n=0; n<3; n++ ) - matrix[phiOffset+m][phiOffset+n] += elementMatrix[localPhiOffset+m][localPhiOffset+n]; - - // printmatrix(std::cout, matrix, "StiffnessMatrix", "--"); - } - } - - - void assembleCellLoad(VectorCT& b, - const Func2Tensor& forceTerm - ) - { - // std::cout << "assemble load vector." << std::endl; - b.resize(basis_.size()+3); - b = 0; - - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - // Transform G_alpha's to GridViewFunctions/LocalFunctions - auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, basis_.gridView()); - auto loadFunctional = localFunction(loadGVF); - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambdaLocal = localFunction(lambdaGridF); - - - // int counter = 1; - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - loadFunctional.bind(element); - - const int localPhiOffset = localView.size(); - // std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - - VectorCT elementRhs; - // std::cout << "----------------------------------Element : " << counter << std::endl; //TEST - // counter++; - computeElementLoadVector(localView, muLocal, lambdaLocal, elementRhs, loadFunctional); - // computeElementLoadVector(localView, muLocal, lambdaLocal, gamma, elementRhs, forceTerm); //TEST - // printvector(std::cout, elementRhs, "elementRhs", "--"); - // printvector(std::cout, elementRhs, "elementRhs", "--"); - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL LOAD ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t p=0; p<localPhiOffset; p++) - { - auto row = localView.index(p); - b[row] += elementRhs[p]; - } - for (size_t m=0; m<3; m++ ) - b[phiOffset+m] += elementRhs[localPhiOffset+m]; - //printvector(std::cout, b, "b", "--"); - } - } - - // ----------------------------------------------------------------- - // --- Functions for global integral mean equals zero constraint - auto arbitraryComponentwiseIndices(const int elementNumber, - const int leafIdx - ) - { - // (Local Approach -- works for non Lagrangian-Basis too) - // Input : elementNumber & localIdx - // Output : determine all Component-Indices that correspond to that basis-function - auto localView = basis_.localView(); - - FieldVector<int,3> row; - int elementCounter = 0; - - for (const auto& element : elements(basis_.gridView())) - { - if(elementCounter == elementNumber) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet - { - localView.bind(element); - - for (int k = 0; k < 3; k++) - { - auto rowLocal = localView.tree().child(k).localIndex(leafIdx); //Input: LeafIndex! TODO bräuchte hier (Inverse ) Local-to-Leaf Idx Map - row[k] = localView.index(rowLocal); - // std::cout << "rowLocal:" << rowLocal << std::endl; - // std::cout << "row[k]:" << row[k] << std::endl; - } - } - elementCounter++; - } - return row; - } - - void setOneBaseFunctionToZero() - { - std::cout << "Setting one Basis-function to zero" << std::endl; - - // constexpr int dim = Basis::LocalView::Element::dimension; - - unsigned int arbitraryLeafIndex = parameterSet_.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet_.template get<unsigned int>("arbitraryElementNumber", 0); - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - FieldVector<int,3> row = arbitraryComponentwiseIndices(arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<dim; k++) - { - 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; - } - } - - - auto childToIndexMap(const int k) - { - // Input : child/component - // Output : determine all Indices that belong to that component - auto localView = basis_.localView(); - - std::vector<int> r = { }; - // for (int n: r) - // std::cout << n << ","<< std::endl; - - // Determine global indizes for each component k = 1,2,3.. in order to subtract correct (component of) integral Mean - // (global) Indices that correspond to component k = 1,2,3 - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - const auto& localFiniteElement = localView.tree().child(k).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - for(size_t j=0; j<nSf; j++) - { - auto Localidx = localView.tree().child(k).localIndex(j); // local indices - r.push_back(localView.index(Localidx)); // global indices - } - } - // Delete duplicate elements - // first remove consecutive (adjacent) duplicates - auto last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - // sort followed by unique, to remove all duplicates - std::sort(r.begin(), r.end()); - last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - return r; - } - - - auto integralMean(VectorCT& coeffVector) - { - auto GVFunction = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(basis_,coeffVector); - auto localfun = localFunction(GVFunction); - - auto localView = basis_.localView(); - - FieldVector<double,3> r = {0.0, 0.0, 0.0}; - double area = 0.0; - - // Compute Area integral & integral of FE-function - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; //TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - area += quadPoint.weight() * integrationElement; - - r += localfun(quadPos) * quadPoint.weight() * integrationElement; - } - } - // std::cout << "Domain-Area: " << area << std::endl; - return (1.0/area) * r ; - } - - - auto subtractIntegralMean(VectorCT& coeffVector) - { - // Substract correct Integral mean from each associated component function - auto IM = integralMean(coeffVector); - - for(size_t k=0; k<dim; k++) - { - //std::cout << "Integral-Mean: " << IM[k] << std::endl; - auto idx = childToIndexMap(k); - for ( int i : idx) - coeffVector[i] -= IM[k]; - } - } - - - // ----------------------------------------------------------------- - // --- Solving the Corrector-problem: - auto solve() - { - std::cout << "start corrector solver..." << std::endl; - bool set_oneBasisFunction_Zero = parameterSet_.get<bool>("set_oneBasisFunction_Zero", false); - bool substract_integralMean = false; - if(parameterSet_.get<bool>("set_IntegralZero", false)) - { - set_oneBasisFunction_Zero = true; - substract_integralMean = true; - } - // set one basis-function to zero - if(set_oneBasisFunction_Zero) - setOneBaseFunctionToZero(); - - //TEST: Compute Condition Number (Can be very expensive !) - const bool verbose = true; - const unsigned int arppp_a_verbosity_level = 2; - const unsigned int pia_verbosity_level = 1; - MatrixInfo<MatrixCT> matrixInfo(stiffnessMatrix_,verbose,arppp_a_verbosity_level,pia_verbosity_level); - std::cout << "Get condition number of Stiffness_CE: " << matrixInfo.getCond2(true) << std::endl; - - /////////////////////////////////// - // --- Choose Solver --- - // 1 : CG-Solver - // 2 : GMRES - // 3 : QR (default) - // 4 : UMFPACK - /////////////////////////////////// - unsigned int Solvertype = parameterSet_.get<unsigned int>("Solvertype", 3); - unsigned int Solver_verbosity = parameterSet_.get<unsigned int>("Solver_verbosity", 2); - - // --- set initial values for solver - x_1_ = load_alpha1_; - x_2_ = load_alpha2_; - x_3_ = load_alpha3_; - - Dune::Timer SolverTimer; - if (Solvertype==1) // CG - SOLVER - { - std::cout << "------------ CG - Solver ------------" << std::endl; - MatrixAdapter<MatrixCT, VectorCT, VectorCT> op(stiffnessMatrix_); - - // Sequential incomplete LU decomposition as the preconditioner - SeqILU<MatrixCT, VectorCT, VectorCT> ilu0(stiffnessMatrix_,1.0); - int iter = parameterSet_.get<double>("iterations_CG", 999); - // Preconditioned conjugate-gradient solver - CGSolver<VectorCT> solver(op, - ilu0, //NULL, - 1e-8, // desired residual reduction factorlack - iter, // maximum number of iterations - Solver_verbosity, - true // Try to estimate condition_number - ); // verbosity of the solver - InverseOperatorResult statistics; - std::cout << "solve linear system for x_1.\n"; - solver.apply(x_1_, load_alpha1_, statistics); - std::cout << "solve linear system for x_2.\n"; - solver.apply(x_2_, load_alpha2_, statistics); - std::cout << "solve linear system for x_3.\n"; - solver.apply(x_3_, load_alpha3_, statistics); - log_ << "Solver-type used: " <<" CG-Solver" << std::endl; - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if (Solvertype==2) // GMRES - SOLVER - { - std::cout << "------------ GMRES - Solver ------------" << std::endl; - // Turn the matrix into a linear operator - MatrixAdapter<MatrixCT,VectorCT,VectorCT> stiffnessOperator(stiffnessMatrix_); - - // Fancy (but only) way to not have a preconditioner at all - Richardson<VectorCT,VectorCT> preconditioner(1.0); - - // Construct the iterative solver - RestartedGMResSolver<VectorCT> solver( - stiffnessOperator, // Operator to invert - preconditioner, // Preconditioner - 1e-10, // Desired residual reduction factor - 500, // Number of iterations between restarts, - // here: no restarting - 500, // Maximum number of iterations - Solver_verbosity); // Verbosity of the solver - - // Object storing some statistics about the solving process - InverseOperatorResult statistics; - - // solve for different Correctors (alpha = 1,2,3) - solver.apply(x_1_, load_alpha1_, statistics); //load_alpha1 now contains the corresponding residual!! - solver.apply(x_2_, load_alpha2_, statistics); - solver.apply(x_3_, load_alpha3_, statistics); - log_ << "Solver-type used: " <<" GMRES-Solver" << std::endl; - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if ( Solvertype==3)// QR - SOLVER - { - std::cout << "------------ QR - Solver ------------" << std::endl; - log_ << "solveLinearSystems: We use QR solver.\n"; - //TODO install suitesparse - SPQR<MatrixCT> sPQR(stiffnessMatrix_); - sPQR.setVerbosity(1); - InverseOperatorResult statisticsQR; - - sPQR.apply(x_1_, load_alpha1_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_2_, load_alpha2_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_3_, load_alpha3_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log_ << "Solver-type used: " <<" QR-Solver" << std::endl; - - } - //////////////////////////////////////////////////////////////////////////////////// - else if (Solvertype==4)// UMFPACK - SOLVER - { - std::cout << "------------ UMFPACK - Solver ------------" << std::endl; - log_ << "solveLinearSystems: We use UMFPACK solver.\n"; - - Dune::Solvers::UMFPackSolver<MatrixCT,VectorCT> solver; - solver.setProblem(stiffnessMatrix_,x_1_,load_alpha1_); - // solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_,x_2_,load_alpha2_); - // solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_,x_3_,load_alpha3_); - // solver.preprocess(); - solver.solve(); - // sPQR.apply(x_1, load_alpha1, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - // sPQR.apply(x_2, load_alpha2, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - // sPQR.apply(x_3, load_alpha3, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log_ << "Solver-type used: " <<" UMFPACK-Solver" << std::endl; - } - std::cout << "Finished solving Corrector problems!" << std::endl; - std::cout << "Time for solving:" << SolverTimer.elapsed() << std::endl; - - //////////////////////////////////////////////////////////////////////////////////// - // Extract phi_alpha & M_alpha coefficients - //////////////////////////////////////////////////////////////////////////////////// - phi_1_.resize(basis_.size()); - phi_1_ = 0; - phi_2_.resize(basis_.size()); - phi_2_ = 0; - phi_3_.resize(basis_.size()); - phi_3_ = 0; - - for(size_t i=0; i<basis_.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]; - } - // assemble M_alpha's (actually iota(M_alpha) ) - - // MatrixRT M_1(0), M_2(0), M_3(0); - - M1_ = 0; - M2_ = 0; - M3_ = 0; - - for(size_t i=0; i<3; i++) - { - M1_ += m_1_[i]*MatrixBasisContainer_[i]; - M2_ += m_2_[i]*MatrixBasisContainer_[i]; - M3_ += m_3_[i]*MatrixBasisContainer_[i]; - } - - std::cout << "--- plot corrector-Matrices M_alpha --- " << std::endl; - printmatrix(std::cout, M1_, "Corrector-Matrix M_1", "--"); - printmatrix(std::cout, M2_, "Corrector-Matrix M_2", "--"); - printmatrix(std::cout, M3_, "Corrector-Matrix M_3", "--"); - log_ << "---------- OUTPUT ----------" << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_1: \n" << M1_ << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_2: \n" << M2_ << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_3: \n" << M3_ << std::endl; - log_ << " --------------------" << std::endl; - - - if(parameterSet_.get<bool>("write_IntegralMean", false)) - { - std::cout << "check integralMean phi_1: " << std::endl; - auto A = integralMean(phi_1_); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean phi_1 : " << A[i] << std::endl; - } - } - if(substract_integralMean) - { - std::cout << " --- substracting integralMean --- " << std::endl; - subtractIntegralMean(phi_1_); - subtractIntegralMean(phi_2_); - subtractIntegralMean(phi_3_); - subtractIntegralMean(x_1_); - subtractIntegralMean(x_2_); - subtractIntegralMean(x_3_); - ////////////////////////////////////////// - // Check Integral-mean again: - ////////////////////////////////////////// - if(parameterSet_.get<bool>("write_IntegralMean", false)) - { - auto A = integralMean(phi_1_); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean phi_1 (Check again) : " << A[i] << std::endl; - } - } - } - ///////////////////////////////////////////////////////// - // Write Solution (Corrector Coefficients) in Logs - ///////////////////////////////////////////////////////// - if(parameterSet_.get<bool>("write_corrector_phi1", false)) - { - log_ << "\nSolution of Corrector problems:\n"; - log_ << "\n Corrector_phi1:\n"; - log_ << x_1_ << std::endl; - } - if(parameterSet_.get<bool>("write_corrector_phi2", false)) - { - log_ << "-----------------------------------------------------"; - log_ << "\n Corrector_phi2:\n"; - log_ << x_2_ << std::endl; - } - if(parameterSet_.get<bool>("write_corrector_phi3", false)) - { - log_ << "-----------------------------------------------------"; - log_ << "\n Corrector_phi3:\n"; - log_ << x_3_ << std::endl; - } - - } - - - // ----------------------------------------------------------------- - // --- Write Correctos to VTK: - void writeCorrectorsVTK(const int level) - { - std::string vtkOutputName = parameterSet_.get("outputPath", "../../outputs") + "/CellProblem-result"; - std::cout << "vtkOutputName:" << vtkOutputName << std::endl; - - VTKWriter<typename Basis::GridView> vtkWriter(basis_.gridView()); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_1_), - VTK::FieldInfo("Corrector phi_1 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_2_), - VTK::FieldInfo("Corrector phi_2 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_3_), - VTK::FieldInfo("Corrector phi_3 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.write(vtkOutputName + "-level"+ std::to_string(level)); - std::cout << "wrote Corrector-VTK data to file: " + vtkOutputName + "-level" + std::to_string(level) << std::endl; - } - - // ----------------------------------------------------------------- - // --- Compute norms of the corrector functions: - void computeNorms() - { - computeL2Norm(); - computeL2SymGrad(); - - std::cout<< "Frobenius-Norm of M1_: " << M1_.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M2_: " << M2_.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M3_: " << M3_.frobenius_norm() << std::endl; - } - - void computeL2Norm() - { - // IMPLEMENTATION with makeDiscreteGlobalBasisFunction - double error_1 = 0.0; - double error_2 = 0.0; - double error_3 = 0.0; - - auto localView = basis_.localView(); - auto GVFunc_1 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_); - auto GVFunc_2 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_); - auto GVFunc_3 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun_1.bind(element); - localfun_2.bind(element); - localfun_3.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - error_1 += localfun_1(quadPos)*localfun_1(quadPos) * quadPoint.weight() * integrationElement; - error_2 += localfun_2(quadPos)*localfun_2(quadPos) * quadPoint.weight() * integrationElement; - error_3 += localfun_3(quadPos)*localfun_3(quadPos) * quadPoint.weight() * integrationElement; - } - } - std::cout << "L2-Norm(Corrector phi_1): " << sqrt(error_1) << std::endl; - std::cout << "L2-Norm(Corrector phi_2): " << sqrt(error_2) << std::endl; - std::cout << "L2-Norm(Corrector phi_3): " << sqrt(error_3) << std::endl; - - return; - } - - void computeL2SymGrad() - { - double error_1 = 0.0; - double error_2 = 0.0; - double error_3 = 0.0; - - auto localView = basis_.localView(); - - auto GVFunc_1 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_)); - auto GVFunc_2 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_)); - auto GVFunc_3 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_)); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun_1.bind(element); - localfun_2.bind(element); - localfun_3.bind(element); - auto geometry = element.geometry(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 ); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const auto integrationElement = geometry.integrationElement(quadPos); - - auto scaledSymGrad1 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_1(quadPos))); - auto scaledSymGrad2 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_2(quadPos))); - auto scaledSymGrad3 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_3(quadPos))); - - error_1 += scalarProduct(scaledSymGrad1,scaledSymGrad1) * quadPoint.weight() * integrationElement; - error_2 += scalarProduct(scaledSymGrad2,scaledSymGrad2) * quadPoint.weight() * integrationElement; - error_3 += scalarProduct(scaledSymGrad3,scaledSymGrad3) * quadPoint.weight() * integrationElement; - } - } - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_1): " << sqrt(error_1) << std::endl; - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_2): " << sqrt(error_2) << std::endl; - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_3): " << sqrt(error_3) << std::endl; - return; - } - - - - // ----------------------------------------------------------------- - // --- Check Orthogonality relation Paper (75) - auto check_Orthogonality() - { - std::cout << "Check Orthogonality..." << std::endl; - - auto localView = basis_.localView(); - - auto GVFunc_1 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_)); - auto GVFunc_2 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_)); - auto GVFunc_3 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_)); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - const std::array<decltype(localfun_1)*,3> phiDerContainer = {&localfun_1 , &localfun_2 , &localfun_3 }; - - auto localIndicatorFunction = material_.getLocalIndicatorFunction(); - - - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto mu = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambda= localFunction(lambdaGridF); - - for(int a=0; a<3; a++) - for(int b=0; b<3; b++) - { - double energy = 0.0; - - auto DerPhi1 = *phiDerContainer[a]; - auto DerPhi2 = *phiDerContainer[b]; - - auto matrixFieldGGVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer_[a], basis_.gridView()); - auto matrixFieldG = localFunction(matrixFieldGGVF); - // auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - // auto matrixFieldB = localFunction(matrixFieldBGVF); - - // using GridView = typename Basis::GridView; - // using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - // using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - // std::cout << "Press key.." << std::endl; - // std::cin.get(); - - // TEST - // FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; - // printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis_.gridView())) - { - localView.bind(e); - matrixFieldG.bind(e); - DerPhi1.bind(e); - DerPhi2.bind(e); - mu.bind(e); - lambda.bind(e); - localIndicatorFunction.bind(e); - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - - auto Chi = sym(crossSectionDirectionScaling(1.0/gamma_, DerPhi2(quadPos))) + *mContainer[b]; - - auto strain1 = DerPhi1(quadPos); - - - strain1 = crossSectionDirectionScaling(1.0/gamma_, strain1); - strain1 = sym(strain1); - - - auto G = matrixFieldG(quadPos); - // auto G = matrixFieldG(e.geometry().global(quadPos)); //TEST - - auto tmp = G + *mContainer[a] + strain1; - - double energyDensity= scalarProduct(material_.ElasticityTensor(tmp,localIndicatorFunction(quadPos)),sym(Chi)); - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), tmp, Chi); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - // elementEnergy += strain1 * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } - if(parameterSet_.get<bool>("print_debug", false)) - std::cout << "check_Orthogonality:" << "("<< a <<"," << b << "): " << energy << std::endl; - - if(energy > 1e-1) - std::cout << "WARNING: check_Orthogonality failed! apparently orthogonality (75) not satisfied on discrete level" << std::endl; - - } - return 0; - } - - - - // --- Check wheter stiffness matrix is symmetric - void checkSymmetry() - { - std::cout << " Check Symmetry of stiffness matrix..." << std::endl; - - auto localView = basis_.localView(); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - const int localPhiOffset = localView.size(); - - for(size_t i=0; i<localPhiOffset; i++) - for(size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - if(abs( stiffnessMatrix_[row][col] - stiffnessMatrix_[col][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - for(size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - if(abs( stiffnessMatrix_[row][phiOffset_+m] - stiffnessMatrix_[phiOffset_+m][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - - } - for(size_t m=0; m<3; m++ ) - for(size_t n=0; n<3; n++ ) - { - if(abs(stiffnessMatrix_[phiOffset_+m][phiOffset_+n] - stiffnessMatrix_[phiOffset_+n][phiOffset_+m]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - } - std::cout << "--- Symmetry test passed ---" << std::endl; - } - - - - - -}; // end class - -#endif \ No newline at end of file diff --git a/src/deprecated_code/30-8-22_TestingFiles-Comments/prestrainedMaterial.hh b/src/deprecated_code/30-8-22_TestingFiles-Comments/prestrainedMaterial.hh deleted file mode 100644 index 3a274edcf111027ab41673537d10aeea589c6d9b..0000000000000000000000000000000000000000 --- a/src/deprecated_code/30-8-22_TestingFiles-Comments/prestrainedMaterial.hh +++ /dev/null @@ -1,284 +0,0 @@ -#ifndef DUNE_MICROSTRUCTURE_PRESTRAINEDMATERIAL_HH -#define DUNE_MICROSTRUCTURE_PRESTRAINEDMATERIAL_HH - - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> -#include <dune/functions/gridfunctions/gridviewentityset.hh> -#include <dune/common/parametertree.hh> -#include <dune/fufem/dunepython.hh> -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/materialDefinitions.hh> - - -using namespace Dune; -using namespace MatrixOperations; -using std::pow; -using std::abs; -using std::sqrt; -using std::sin; -using std::cos; - -using std::shared_ptr; -using std::make_shared; - - - - - -// template<class Domain> -// MatrixRT MAT(const MatrixRT& G, const Domain& x) //unfortunately not possible as a GridViewFunction? -// { -// const FieldVector<double,3> mu = {80.0, 80.0, 60.0}; -// const FieldVector<double,3> lambda = {80.0, 80.0, 25.0}; -// double theta=0.25; -// if (x[0] <(-0.5+theta) and x[2]<(-0.5+theta)) -// return 2.0 * mu[0] * sym(G) + lambda[0] * trace(sym(G)) * Id(); -// else if (x[1]<(-0.5+theta) and x[2]>(0.5-theta)) -// return 2.0 * mu[1] * sym(G) + lambda[1] * trace(sym(G)) * Id(); -// else -// return 2.0 * mu[2] * sym(G) + lambda[2] * trace(sym(G)) * Id(); -// } - -template <class GridView> // needed for GridViewFunctions -class prestrainedMaterial -{ - -public: - static const int dimworld = 3; //GridView::dimensionworld; - static const int dim = 3; //const int dim = Domain::dimension; - - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using LocalDomain = typename GridView::template Codim<0>::Geometry::LocalCoordinate; - using Element = typename GridViewEntitySet<GridView, 0>::Element; - using ScalarRT = FieldVector< double, 1>; - using VectorRT = FieldVector< double, dimworld>; - using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - using FuncScalar = std::function< double(const Domain&) >; - using Func2int = std::function< int(const Domain&) >; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - using Func2TensorParam = std::function< MatrixRT(const MatrixRT& ,const Domain&) >; - using Func2TensorPhase = std::function< MatrixRT(const MatrixRT& ,const int&) >; - using MatrixFunc = std::function< MatrixRT(const MatrixRT&) >; - using MatrixPhase = std::function< MatrixRT(const int&) >; - -protected: - - const GridView& gridView_; - const ParameterTree& parameterSet_; - std::string materialFunctionName_; - - // MatrixFunc L1_; - // MatrixFunc L2_; - // MatrixFunc L3_; - // const FuncScalar mu_; - // const FuncScalar lambda_; - // const int phases_; - // Func2Tensor elasticityTensor_; - // Func2TensorParam elasticityTensor_; - Func2TensorPhase elasticityTensor_; - MatrixPhase prestrain_; - - - Func2int indicatorFunction_; - GridViewFunction<int(const Domain&), GridView> indicatorFunctionGVF_; - LocalFunction<int(const Domain&), typename GridViewEntitySet<GridView, 0>::Element > localIndicatorFunction_; - -public: - /////////////////////////////// - // constructor - /////////////////////////////// - prestrainedMaterial(const GridView gridView, - const ParameterTree& parameterSet) - : gridView_(gridView), - parameterSet_(parameterSet) - { - std::string materialFunctionName_ = parameterSet.get<std::string>("materialFunction", "material_1"); - std::cout << "materialFunctionName_ : " << materialFunctionName_ << std::endl; - - setupMaterial(materialFunctionName_); - - indicatorFunctionGVF_ = Dune::Functions::makeGridViewFunction(indicatorFunction_, gridView_); - localIndicatorFunction_ = localFunction(indicatorFunctionGVF_); - - // Python::Module module = Python::import(materialFunctionName_); - // elasticityTensor_ = Python::make_function<MatrixRT>(module.get("L")); - // elasticityTensor_ = setupElasticityTensor(materialFunctionName_); - // auto indicatorFunction = Python::make_function<int>(module.get("indicatorFunction")); - // indicatorFunction_ = Python::make_function<int>(module.get("indicatorFunction")); - // indicatorFunction_ = Dune::Functions::makeGridViewFunction(indicatorFunction , gridView_); - // module.get("Phases").toC<int>(Phases_); - // L1_ = Python::make_function<MatrixRT>(module.get("L1")); - // L2_ = Python::make_function<MatrixRT>(module.get("L2")); - // L3_ = Python::make_function<MatrixRT>(module.get("L3")); - // bool isotropic_ = true; // read from module File - // auto Test = Dune::Functions::makeGridViewFunction(MAT<Domain> , gridView_); //not working - } - - //---function that determines elasticity Tensor - void setupMaterial(const std::string name) // cant use materialFunctionName_ here!? - { - // std::cout << "Using material definition:" << name << std::endl; - if(name == "material_neukamm") - { - indicatorFunction_ = indicatorFunction_material_neukamm<Domain>; - elasticityTensor_ = material_neukamm; - prestrain_ = prestrain_material_neukamm; - } - else if(name == "two_phase_material_1") - { - indicatorFunction_ = indicatorFunction_two_phase_material_1<Domain>; - elasticityTensor_ = two_phase_material_1; - prestrain_ = prestrain_two_phase_material_1; - } - else if(name == "two_phase_material_2") - { - indicatorFunction_ = indicatorFunction_two_phase_material_2<Domain>; - elasticityTensor_ = two_phase_material_2; - prestrain_ = prestrain_two_phase_material_2; - } - else if(name == "homogeneous") - { - indicatorFunction_ = indicatorFunction_material_homogeneous<Domain>; - elasticityTensor_ = material_homogeneous; - prestrain_ = prestrain_homogeneous; - } - else - DUNE_THROW(Exception, "There exists no material with this name "); - } - - - //--- apply elasticityTensor_ to input Matrix G at position x - // input: Matrix G, material-phase - MatrixRT ElasticityTensor(const MatrixRT& G, const int& phase) const - { - return elasticityTensor_(G,phase); - - } - - int IndicatorFunction(const Domain& x) const - { - return indicatorFunction_(x); - } - - // static int indicatorFunction_material_1(const Domain& x) - // { - // // std::cout << "x[0] , x[1] , x[2]" << x[0] << " , " << x[1] << ", "<< x[2] << std::endl; - // double theta=0.25; - // std::cout << "-1/2" << -1/2 << std::endl; - // if ((x[1]< (-0.5+theta)) and (x[2]>(0.5-theta))) - // { - // return 2; //#Phase1 - // } - // else if ((x[0] < (-0.5+theta)) and (x[2]<(-0.5+theta))) - // { - // return 1; //#Phase2 - // } - // else - // { - // return 0; //#Phase3 - // } - // } - - - - // MatrixRT localElasticityTensor(const MatrixRT& G, const Domain& x, Element& element) const //local Version ... muss binding öfters durchführen - // { - // localIndicatorFunction_.bind(*element); - // return elasticityTensor_(G,localIndicatorFunction_(x)); - // } - - - - - // MatrixRT ElasticityTensorGlobal(const MatrixRT& G, const Domain& x) const //global Version (takes global coordinates) - // { - // return MAT(G,x); - // } - - - // //--- apply elasticityTensor_ to input Matrix G at position x - // MatrixRT applyElasticityTensor(const MatrixRT& G, const Domain& x) const //global Version (takes global coordinates) - // { - // // Python::Module module = Python::import("material"); - // // auto indicatorFunctionTest = Python::make_function<double>(module.get("indicatorFunction")); - // // return elasticityTensor_(G,indicatorFunctionTest(x)); - // // auto IFunction = localFunction(indicatorFunction_); - // // auto IFunction = this->getIndicatorFunction(); - // // auto tmp = Dune::Functions::makeGridViewFunction(indicatorFunction_material_1, gridView_); - // // auto tmpLocal = LocalF - // // return elasticityTensor_(G,IFunction(x)); - // // return elasticityTensor_(G,localIndicatorFunction_(x)); - // return elasticityTensor_(G,indicatorFunction_(x)); - // // return elasticityTensor_(G,indicatorFunctionGVF_(x)); - // // int phase = indicatorFunction_(x); - // // auto tmp = elasticityTensor_(G,phase); - // // auto tmp = material_1(G,indicatorFunction_(x)); - // // printmatrix(std::cout, material_1(G,indicatorFunction_(x)), "material_1(G,indicatorFunction_(x))", "--"); - // // printmatrix(std::cout, elasticityTensor_(G,phase), "elasticityTensor_(G,phase)", "--"); - // // return tmp; - // // return material_1(G,indicatorFunction_(x)); - // } - - - -////////////////////////////////////////////////////////////////////////////// - // MatrixRT applyElasticityTensor(const MatrixRT& G, const Domain& x) const - // { - // //--- apply elasticityTensor_ to input Matrix G at position x - // return elasticityTensor_(G,x); - - // } - - // MatrixRT applyElasticityTensorLocal(const MatrixRT& G, const Domain& x) const - // { - // //--- apply elasticityTensor_ to input Matrix G at position x (local coordinates) - // // MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - - // if (indicatorFunction_(x) == 1) - // return L1_(G); - // else if (indicatorFunction_(x) == 2) - // return L2_(G); - // else - // return L3_(G); - - // } - - - // ----------------------------------------------------------------- - // --- write material (grid)functions to VTK - void write_materialFunctions() - { - - - return; - - }; - /////////////////////////////// - // Getter - /////////////////////////////// - ParameterTree getParameterSet() const {return parameterSet_;} - // Func2Tensor getElasticityTensor() const {return elasticityTensor_;} - // Func2TensorParam getElasticityTensor() const {return elasticityTensor_;} - Func2TensorPhase getElasticityTensor() const {return elasticityTensor_;} - MatrixPhase getPrestrainFunction() const {return prestrain_;} - - auto getLocalIndicatorFunction() const {return localIndicatorFunction_;} //get as localFunction - auto getIndicatorFunctionGVF() const {return indicatorFunctionGVF_;} //get as GridViewFunction - auto getIndicatorFunction() const {return indicatorFunction_;} - - - // shared_ptr<Func2int> getIndicatorFunction(){return make_shared<Func2int>(indicatorFunction_);} - // auto getIndicatorFunction(){return make_shared<Func2int>(indicatorFunction_);} - // shared_ptr<Func2TensorParam> getElasticityTensor(){return make_shared<Func2TensorParam>(elasticityTensor_);} - - //getLameParameters() .. Throw Exception if isotropic_ = false! - - - - -}; // end class - - -#endif diff --git a/src/deprecated_code/31-8-22_prestrainedMaterials/material_backup.py b/src/deprecated_code/31-8-22_prestrainedMaterials/material_backup.py deleted file mode 100644 index 141ccab4956c1b2ee26047b3e6d19d5f964e1dc3..0000000000000000000000000000000000000000 --- a/src/deprecated_code/31-8-22_prestrainedMaterials/material_backup.py +++ /dev/null @@ -1,251 +0,0 @@ -import math -from python_matrix_operations import * -import ctypes -import os -import sys - - -Phases=3 - -mu_ = [80, 80, 60] -lambda_ = [80, 80, 25] - - -phase1_type="isotropic" -materialParameters_phase1 = [80, 80] - -phase2_type="isotropic" -materialParameters_phase2 = [80, 80] - -phase3_type="isotropic" -materialParameters_phase3 = [60, 25] - - -# print('mu_:', mu_) -# A = [[1, 5, 0], [5,1,0], [5,0,1]] -# -# print("sym(A):", sym(A)) - - -# dir_path = os.path.dirname(os.path.realpath("/home/klaus/Desktop/Dune-Testing/dune-microstructure/dune/microstructure/matrix_operations.hh")) -# handle = ctypes.CDLL(dir_path) -# -# handle.create2Darray.argtypes = [ctypes.c_int, ctypes.c_double, ctypes.c_double] -# -# def create2Darray(nside, mx, my): -# return handle.create2Darray(nside, mx, my) - - -#Indicator function that determines both phases -# x[0] : y1-component -# x[1] : y2-component -# x[2] : x3-component -# --- replace with your definition of indicatorFunction: -############### -# Wood -############### -# def f(x): -# theta=0.25 -# # mu_ = [3, 5, 6] -# # lambda_ = [9, 7, 8] -# # mu_ = 3 5 6 -# # lambda_ = 9 7 8 - -# if ((abs(x[0]) < theta/2) and x[2]<0.25): -# return [mu_[0], lambda_[0]] #latewood -# # return 5 #latewood -# elif ((abs(x[0]) > theta/2) and x[2]<0.25): -# return [mu_[1], lambda_[1]] #latewood -# # return 2 -# else : -# return [mu_[2],lambda_[2]] #latewood #Phase3 -# # return 1 - -def indicatorFunction(x): - theta=0.25 - factor=1 - if (x[0] <-1/2+theta and x[2]<-1/2+theta): - return 1 #Phase1 - elif (x[1]< -1/2+theta and x[2]>1/2-theta): - return 2 #Phase2 - else : - return 0 #Phase3 - - -def L1(G): - return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 - -def L2(G): - return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 - -def L3(G): - return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 - - -# TEST - -# def L1(G): -# return Add(smult(2.0 * mu_[0], sym(G)),smult(lambda_[0] ,smult(trace(sym(G)),Id()) )) #Phase1 - -# def L2(G): -# return Add(smult(2.0 * mu_[1], sym(G)),smult(lambda_[1] ,smult(trace(sym(G)),Id()) )) #Phase1 - -# def L3(G): -# return Add(smult(2.0 * mu_[2], sym(G)),smult(lambda_[2] ,smult(trace(sym(G)),Id()) )) #Phase1 - - -#Workaround -def muValue(x): - return mu_ - -def lambdaValue(x): - return lambda_ - - - - - -############### -# Cross -############### -# def f(x): -# theta=0.25 -# factor=1 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# return 1 #Phase1 -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return 2 #Phase2 -# else : -# return 0 #Phase3 - - - - - -# def f(x): -# # --- replace with your definition of indicatorFunction: -# if (abs(x[0]) > 0.25): -# return 1 #Phase1 -# else : -# return 0 #Phase2 - -def b1(x): - return [[1, 0, 0], [0,1,0], [0,0,1]] - -def b2(x): - return [[1, 0, 0], [0,1,0], [0,0,1]] - -def b3(x): - return [[0, 0, 0], [0,0,0], [0,0,0]] - -# mu=80 80 60 - -# lambda=80 80 25 - - -# --- elasticity tensor -# def L(G,x): -# def L(G): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] - - - - - - - - - -# --- elasticity tensor -def L(G,x): - # input: symmetric matrix G, position x - # output: symmetric matrix LG - theta=0.25 - if (x[0] <-1/2+theta and x[2]<-1/2+theta): - return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 - elif (x[1]< -1/2+theta and x[2]>1/2-theta): - return 2.0 * mu_[1] * sym(G) + lambda_[1] * trace(sym(G)) * Id() #Phase2 - else : - return 2.0 * mu_[2] * sym(G) + lambda_[2] * trace(sym(G)) * Id() #Phase3 -# # # 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id(); - - -# def L(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# theta=0.25 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# # return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 -# return Add(smult(2.0 * mu_[0], sym(G)),smult(lambda_[0] ,smult(trace(sym(G)),Id()) )) -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return Add(smult(2.0 * mu_[0], sym(G)),smult(lambda_[0] ,smult(trace(sym(G)),Id()) )) #Phase2 -# else : -# return Add(smult(2.0 * mu_[0], sym(G)),smult(lambda_[0] ,smult(trace(sym(G)),Id()) )) #Phase3 -# # return [[0, 0, 0], [0,0,0], [0,0,0]] #Phase3 - - -##TEST -# def L(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# theta=0.25 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return [[x[0], 1, x[0]], [1, 1, 1],[x[0], x[0], x[0]]] -# else : -# return [[0, x[2], x[2]], [0,x[2],0], [0,0,0]] - - -##TEST -# def L(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# theta=0.25 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# return sym([[1, 1, 1], [1, 1, 1],[1, 1, 1]]) -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return sym([[x[0], 1, x[0]], [1, 1, 1],[x[0], x[0], x[0]]]) -# else : -# return sym([[0, x[2], x[2]], [0,x[2],0], [0,0,0]]) - - - -# # small speedup.. -# def L(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# theta=0.25 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# return mu_[0] * (np.array(G).transpose() + np.array(G)) + lambda_[0] * (G[0][0] + G[1][1] + G[2][2]) * np.identity(3) #Phase1 -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return mu_[1] * (np.array(G).transpose() + np.array(G)) + lambda_[1] * (G[0][0] + G[1][1] + G[2][2]) * np.identity(3) #Phase2 -# else : -# return mu_[2] * (np.array(G).transpose() + np.array(G)) + lambda_[2] * (G[0][0] + G[1][1] + G[2][2]) * np.identity(3) #Phase3 -# # 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id(); - - - - - - -# def H(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# if (abs(x[0]) > 0.25): -# return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] -# else: -# return [[0, 0, 0], [0,0,0], [0,0,0]] - - -def H(G,x): - # input: symmetric matrix G, position x - # output: symmetric matrix LG - if (abs(x[0]) > 0.25): - return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] - else: - return [[0, 0, 0], [0,0,0], [0,0,0]] - -# 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id(); diff --git a/src/deprecated_code/Cell-Problem_muGamma.cc b/src/deprecated_code/Cell-Problem_muGamma.cc deleted file mode 100644 index 5a8ef8840c573947c20e65702ca025dcf9b92913..0000000000000000000000000000000000000000 --- a/src/deprecated_code/Cell-Problem_muGamma.cc +++ /dev/null @@ -1,1142 +0,0 @@ -#include <config.h> -#include <array> -#include <vector> -#include <fstream> - -#include <iostream> -#include <dune/common/indices.hh> -#include <dune/common/bitsetvector.hh> -#include <dune/common/parametertree.hh> -#include <dune/common/parametertreeparser.hh> -#include <dune/common/float_cmp.hh> -#include <dune/common/math.hh> - -#include <dune/geometry/quadraturerules.hh> - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -#include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh> - -#include <dune/istl/matrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/multitypeblockmatrix.hh> -#include <dune/istl/multitypeblockvector.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/istl/solvers.hh> -#include <dune/istl/spqr.hh> -#include <dune/istl/preconditioners.hh> -#include <dune/istl/io.hh> - -#include <dune/functions/functionspacebases/interpolate.hh> - -#include <dune/functions/backends/istlvectorbackend.hh> -#include <dune/functions/functionspacebases/powerbasis.hh> -#include <dune/functions/functionspacebases/compositebasis.hh> - -#include <dune/functions/functionspacebases/lagrangebasis.hh> -#include <dune/functions/functionspacebases/periodicbasis.hh> - -#include <dune/functions/functionspacebases/subspacebasis.hh> -#include <dune/functions/functionspacebases/boundarydofs.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> - -#include <dune/common/fvector.hh> -#include <dune/common/fmatrix.hh> - -#include <dune/microstructure/prestrain_material_geometry.hh> -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/vtk_filler.hh> //TEST - - -#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh> - -// #include <dune/fufem/discretizationerror.hh> -// #include <boost/multiprecision/cpp_dec_float.hpp> -// #include <boost/any.hpp> - -#include <any> -#include <variant> -#include <string> -#include <iomanip> - -using namespace Dune; -using namespace MatrixOperations; - -// ------------------------------------------------------------------------ -// -// This is a stripped-down Version of Cell-Problem.cc -// that only computes mu_gamma = q_3 in a faster manner -// i.e. only the third corrector phi_3 is needed. -// ------------------------------------------------------------------------ - - - - - - - - - - - - - -////////////////////////////////////////////////////////////////////// -// Helper functions for Table-Output -////////////////////////////////////////////////////////////////////// -/*! Center-aligns string within a field of width w. Pads with blank spaces - to enforce alignment. */ -std::string center(const std::string s, const int w) { - std::stringstream ss, spaces; - int padding = w - s.size(); // count excess room to pad - for(int i=0; i<padding/2; ++i) - spaces << " "; - ss << spaces.str() << s << spaces.str(); // format with padding - if(padding>0 && padding%2!=0) // if odd #, add 1 space - ss << " "; - return ss.str(); -} - -/* Convert double to string with specified number of places after the decimal - and left padding. */ -template<class type> -std::string prd(const type x, const int decDigits, const int width) { - std::stringstream ss; -// ss << std::fixed << std::right; - ss << std::scientific << std::right; // Use scientific Output! - ss.fill(' '); // fill space around displayed # - ss.width(width); // set width around displayed # - ss.precision(decDigits); // set # places after decimal - ss << x; - return ss.str(); -} - - - - - -template<class Basis> -auto arbitraryComponentwiseIndices(const Basis& basis, - const int elementNumber, - const int leafIdx - ) -{ - // (Local Approach -- works for non Lagrangian-Basis too) - // Input : elementNumber & localIdx - // Output : determine all Component-Indices that correspond to that basis-function - auto localView = basis.localView(); - - FieldVector<int,3> row; - int elementCounter = 0; - - for (const auto& element : elements(basis.gridView())) - { - if(elementCounter == elementNumber) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet - { - localView.bind(element); - - for (int k = 0; k < 3; k++) - { - auto rowLocal = localView.tree().child(k).localIndex(leafIdx); //Input: LeafIndex! TODO bräuchte hier (Inverse ) Local-to-Leaf Idx Map - row[k] = localView.index(rowLocal); - // std::cout << "rowLocal:" << rowLocal << std::endl; - // std::cout << "row[k]:" << row[k] << std::endl; - } - } - elementCounter++; - } - return row; -} - - - - -template<class LocalView, class Matrix, class localFunction1, class localFunction2> -void computeElementStiffnessMatrix(const LocalView& localView, - Matrix& elementMatrix, - const localFunction1& mu, - const localFunction2& lambda, - const double gamma - ) -{ - // Local StiffnessMatrix of the form: - // | phi*phi m*phi | - // | phi *m m*m | - using Element = typename LocalView::Element; - const Element element = localView.element(); - auto geometry = element.geometry(); - constexpr int dim = Element::dimension; - constexpr int dimWorld = dim; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - elementMatrix.setSize(localView.size()+3, localView.size()+3); //extend by dim ´R_sym^{2x2} - elementMatrix = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); -// std::cout << "localView.size(): " << localView.size() << std::endl; -// std::cout << "nSf : " << nSf << std::endl; - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} // wird nicht als Funktion benötigt da konstant... - ////////////////////////////////////////////// - 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, 1.0/sqrt(2), 0.0}, {1.0/sqrt(2), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(quadPos); - const auto integrationElement = geometry.integrationElement(quadPos); - - std::vector< FieldMatrix< double, 1, dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, - referenceGradients); - // Compute the shape function gradients on the grid element - std::vector<FieldVector<double,dim> > gradients(referenceGradients.size()); - - for (size_t i=0; i<gradients.size(); i++) - jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]); - - for (size_t k=0; k < dimWorld; k++) - for (size_t i=0; i < nSf; i++) - { - // "phi*phi"-part - for (size_t l=0; l< dimWorld; l++) - for (size_t j=0; j < nSf; j++ ) - { - // (scaled) Deformation gradient of the ansatz basis function - MatrixRT defGradientU(0); - defGradientU[k][0] = gradients[i][0]; // Y - defGradientU[k][1] = gradients[i][1]; //X2 - defGradientU[k][2] = (1.0/gamma)*gradients[i][2]; //X3 - // printmatrix(std::cout, defGradientU , "defGradientU", "--"); - // (scaled) Deformation gradient of the test basis function - MatrixRT defGradientV(0); - defGradientV[l][0] = gradients[j][0]; // Y - defGradientV[l][1] = gradients[j][1]; //X2 - defGradientV[l][2] = (1.0/gamma)*gradients[j][2]; //X3 - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); -// double energyDensity = generalizedDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); // also works.. - - size_t col = localView.tree().child(k).localIndex(i); - size_t row = localView.tree().child(l).localIndex(j); - elementMatrix[row][col] += energyDensity * quadPoint.weight() * integrationElement; - - // "m*phi" & "phi*m" - part - for( size_t m=0; m<3; m++) - { - double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV); - - auto value = energyDensityGphi * quadPoint.weight() * integrationElement; - elementMatrix[row][localPhiOffset+m] += value; - elementMatrix[localPhiOffset+m][row] += value; - } - } - } - // "m*m"-part - for(size_t m=0; m<3; m++) - for(size_t n=0; n<3; n++) - { - double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n]); - elementMatrix[localPhiOffset+m][localPhiOffset+n]= energyDensityGG * quadPoint.weight() * integrationElement; - } - } -} - - - -// Get the occupation pattern of the stiffness matrix -template<class Basis, class ParameterSet> -void getOccupationPattern(const Basis& basis, MatrixIndexSet& nb, ParameterSet& parameterSet) -{ - // OccupationPattern: - // | phi*phi m*phi | - // | phi *m m*m | - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - nb.resize(basis.size()+3, basis.size()+3); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - for (size_t i=0; i<localView.size(); i++) - { - // The global index of the i-th vertex of the element - auto row = localView.index(i); - for (size_t j=0; j<localView.size(); j++ ) - { - // The global index of the j-th vertex of the element - auto col = localView.index(j); - nb.add(row[0],col[0]); // nun würde auch nb.add(row,col) gehen.. - } - } - for (size_t i=0; i<localView.size(); i++) - { - auto row = localView.index(i); - - for (size_t j=0; j<3; j++ ) - { - nb.add(row,phiOffset+j); // m*phi part of StiffnessMatrix - nb.add(phiOffset+j,row); // phi*m part of StiffnessMatrix - } - } - for (size_t i=0; i<3; i++ ) - for (size_t j=0; j<3; j++ ) - { - nb.add(phiOffset+i,phiOffset+j); // m*m part of StiffnessMatrix - } - } - ////////////////////////////////////////////////////////////////// - // setOneBaseFunctionToZero - ////////////////////////////////////////////////////////////////// - if(parameterSet.template get<bool>("set_oneBasisFunction_Zero ", true)){ - FieldVector<int,3> row; - unsigned int arbitraryLeafIndex = parameterSet.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet.template get<unsigned int>("arbitraryElementNumber", 0); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); // macht keinen Unterschied ob hier k oder 0.. - const auto nSf = localFiniteElement.localBasis().size(); - assert(arbitraryLeafIndex < nSf ); - assert(arbitraryElementNumber < basis.gridView().size(0)); // "arbitraryElementNumber larger than total Number of Elements" - - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - row = arbitraryComponentwiseIndices(basis,arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<3; k++) - nb.add(row[k],row[k]); - } -} - - - -// Compute the source term for a single element -// < L (sym[D_gamma*nabla phi_i] + M_i ), x_3G_alpha > -template<class LocalView, class LocalFunction1, class LocalFunction2, class Vector, class Force> -void computeElementLoadVector( const LocalView& localView, - LocalFunction1& mu, - LocalFunction2& lambda, - const double gamma, - Vector& elementRhs, - const Force& forceTerm - ) -{ - // | f*phi| - // | --- | - // | f*m | - using Element = typename LocalView::Element; - const auto element = localView.element(); - const auto geometry = element.geometry(); - constexpr int dim = Element::dimension; - constexpr int dimWorld = dim; - - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - // Set of shape functions for a single element - const auto& localFiniteElement= localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - elementRhs.resize(localView.size() +3); - elementRhs = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - 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, 1.0/sqrt(2), 0.0}, {1.0/sqrt(2), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - -// int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); // für simplex - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const FieldVector<double,dim>& quadPos = quadPoint.position(); - const auto jacobian = geometry.jacobianInverseTransposed(quadPos); - const double integrationElement = geometry.integrationElement(quadPos); - - std::vector<FieldMatrix<double,1,dim> > referenceGradients; - - localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients); - - std::vector< FieldVector< double, dim> > gradients(referenceGradients.size()); - for (size_t i=0; i< gradients.size(); i++) - jacobian.mv(referenceGradients[i][0], gradients[i]); - - // "f*phi"-part - for (size_t i=0; i < nSf; i++) - for (size_t k=0; k < dimWorld; k++) - { - // Deformation gradient of the ansatz basis function - MatrixRT defGradientV(0); - defGradientV[k][0] = gradients[i][0]; // Y - defGradientV[k][1] = gradients[i][1]; // X2 - defGradientV[k][2] = (1.0/gamma)*gradients[i][2]; // X3 - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientV, forceTerm(quadPos)); - size_t row = localView.tree().child(k).localIndex(i); - elementRhs[row] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "f*m"-part - for (size_t m=0; m<3; m++) - { - double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], forceTerm(quadPos)); - elementRhs[localPhiOffset+m] += energyDensityfG * quadPoint.weight() * integrationElement; - } - } -} - - - -template<class Basis, class Matrix, class LocalFunction1, class LocalFunction2, class ParameterSet> -void assembleCellStiffness(const Basis& basis, - LocalFunction1& muLocal, - LocalFunction2& lambdaLocal, - const double gamma, - Matrix& matrix, - ParameterSet& parameterSet - ) -{ - std::cout << "assemble Stiffness-Matrix begins." << std::endl; - - MatrixIndexSet occupationPattern; - getOccupationPattern(basis, occupationPattern, parameterSet); - occupationPattern.exportIdx(matrix); - matrix = 0; - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - const int localPhiOffset = localView.size(); - - //std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - Dune::Matrix<FieldMatrix<double,1,1> > elementMatrix; - computeElementStiffnessMatrix(localView, elementMatrix, muLocal, lambdaLocal, gamma); - //printmatrix(std::cout, elementMatrix, "ElementMatrix", "--"); - //std::cout << "elementMatrix.N() : " << elementMatrix.N() << std::endl; - //std::cout << "elementMatrix.M() : " << elementMatrix.M() << std::endl; - - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL STIFFNES ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - matrix[row][col] += elementMatrix[i][j]; - } - for (size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - matrix[row][phiOffset+m] += elementMatrix[i][localPhiOffset+m]; - matrix[phiOffset+m][row] += elementMatrix[localPhiOffset+m][i]; - } - for (size_t m=0; m<3; m++ ) - for (size_t n=0; n<3; n++ ) - matrix[phiOffset+m][phiOffset+n] += elementMatrix[localPhiOffset+m][localPhiOffset+n]; - - // printmatrix(std::cout, matrix, "StiffnessMatrix", "--"); - } -} - - -template<class Basis, class LocalFunction1, class LocalFunction2, class Vector, class Force> -void assembleCellLoad(const Basis& basis, - LocalFunction1& muLocal, - LocalFunction2& lambdaLocal, - const double gamma, - Vector& b, - const Force& forceTerm - ) -{ - // std::cout << "assemble load vector." << std::endl; - b.resize(basis.size()+3); - b = 0; - - auto localView = basis.localView(); - const int phiOffset = basis.dimension(); - - // Transform G_alpha's to GridViewFunctions/LocalFunctions - auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, basis.gridView()); - auto loadFunctional = localFunction(loadGVF); - - for (const auto& element : elements(basis.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - loadFunctional.bind(element); - - const int localPhiOffset = localView.size(); - // std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - - BlockVector<FieldVector<double,1> > elementRhs; - computeElementLoadVector(localView, muLocal, lambdaLocal, gamma, elementRhs, loadFunctional); -// printvector(std::cout, elementRhs, "elementRhs", "--"); -// printvector(std::cout, elementRhs, "elementRhs", "--"); - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL LOAD ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t p=0; p<localPhiOffset; p++) - { - auto row = localView.index(p); - b[row] += elementRhs[p]; - } - for (size_t m=0; m<3; m++ ) - b[phiOffset+m] += elementRhs[localPhiOffset+m]; - //printvector(std::cout, b, "b", "--"); - } -} - - - -template<class Basis, class LocalFunction1, class LocalFunction2, class MatrixFunction> -auto energy(const Basis& basis, - LocalFunction1& mu, - LocalFunction2& lambda, - const MatrixFunction& matrixFieldFuncA, - const MatrixFunction& matrixFieldFuncB) -{ - -// TEST HIGHER PRECISION -// using float_50 = boost::multiprecision::cpp_dec_float_50; -// float_50 higherPrecEnergy = 0.0; - double energy = 0.0; - constexpr int dim = Basis::LocalView::Element::dimension; - constexpr int dimWorld = dim; - - auto localView = basis.localView(); - - auto matrixFieldAGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncA, basis.gridView()); - auto matrixFieldA = localFunction(matrixFieldAGVF); - auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - auto matrixFieldB = localFunction(matrixFieldBGVF); - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; -// TEST -// FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; -// printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldA.bind(e); - matrixFieldB.bind(e); - mu.bind(e); - lambda.bind(e); - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - //int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - auto strain1 = matrixFieldA(quadPos); - auto strain2 = matrixFieldB(quadPos); - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), strain1, strain2); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } -// TEST -// std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return energy; -} - - - -template<class Basis, class Matrix, class Vector, class ParameterSet> // changed to take only one load... -void setOneBaseFunctionToZero(const Basis& basis, - Matrix& stiffnessMatrix, - Vector& load_alpha, - ParameterSet& parameterSet - ) -{ - std::cout << "Setting one Basis-function to zero" << std::endl; - - constexpr int dim = Basis::LocalView::Element::dimension; - - unsigned int arbitraryLeafIndex = parameterSet.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet.template get<unsigned int>("arbitraryElementNumber", 0); - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - FieldVector<int,3> row = arbitraryComponentwiseIndices(basis,arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k < dim; k++) - { - load_alpha[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; - } -} - - - -template<class Basis> -auto childToIndexMap(const Basis& basis, - const int k - ) -{ - // Input : child/component - // Output : determine all Indices that belong to that component - auto localView = basis.localView(); - - std::vector<int> r = { }; - // for (int n: r) - // std::cout << n << ","<< std::endl; - - // Determine global indizes for each component k = 1,2,3.. in order to subtract correct (component of) integral Mean - // (global) Indices that correspond to component k = 1,2,3 - for(const auto& element : elements(basis.gridView())) - { - localView.bind(element); - const auto& localFiniteElement = localView.tree().child(k).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - for(size_t j=0; j<nSf; j++) - { - auto Localidx = localView.tree().child(k).localIndex(j); // local indices - r.push_back(localView.index(Localidx)); // global indices - } - } - // Delete duplicate elements - // first remove consecutive (adjacent) duplicates - auto last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - // sort followed by unique, to remove all duplicates - std::sort(r.begin(), r.end()); - last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - - return r; -} - - -template<class Basis, class Vector> -auto integralMean(const Basis& basis, - Vector& coeffVector - ) -{ - // computes integral mean of given LocalFunction - - constexpr int dim = Basis::LocalView::Element::dimension; - - auto GVFunction = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(basis,coeffVector); - auto localfun = localFunction(GVFunction); - - auto localView = basis.localView(); - - FieldVector<double,3> r = {0.0, 0.0, 0.0}; - double area = 0.0; - - // Compute Area integral & integral of FE-function - for(const auto& element : elements(basis.gridView())) - { - localView.bind(element); - localfun.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - area += quadPoint.weight() * integrationElement; - - r += localfun(quadPos) * quadPoint.weight() * integrationElement; - } - } - // std::cout << "Domain-Area: " << area << std::endl; - return (1.0/area) * r ; -} - - -template<class Basis, class Vector> -auto subtractIntegralMean(const Basis& basis, - Vector& coeffVector - ) -{ - // Substract correct Integral mean from each associated component function - auto IM = integralMean(basis, coeffVector); - - constexpr int dim = Basis::LocalView::Element::dimension; - - for(size_t k=0; k<dim; k++) - { - //std::cout << "Integral-Mean: " << IM[k] << std::endl; - auto idx = childToIndexMap(basis,k); - - for ( int i : idx) - coeffVector[i] -= IM[k]; - } -} - - - -////////////////////////////////////////////////// -// Infrastructure for handling periodicity -////////////////////////////////////////////////// - -// Check whether two points are equal on R/Z x R/Z x R -auto equivalent = [](const FieldVector<double,3>& x, const FieldVector<double,3>& y) - { - return ( (FloatCmp::eq(x[0],y[0]) or FloatCmp::eq(x[0]+1,y[0]) or FloatCmp::eq(x[0]-1,y[0])) - and (FloatCmp::eq(x[1],y[1]) or FloatCmp::eq(x[1]+1,y[1]) or FloatCmp::eq(x[1]-1,y[1])) - and (FloatCmp::eq(x[2],y[2])) - ); - }; - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int main(int argc, char *argv[]) -{ - MPIHelper::instance(argc, argv); - - ParameterTree parameterSet; - if (argc < 2) - ParameterTreeParser::readINITree("../../inputs/cellsolver.parset", parameterSet); - else - { - ParameterTreeParser::readINITree(argv[1], parameterSet); - ParameterTreeParser::readOptions(argc, argv, parameterSet); - } - - // Output setter -// std::string outputPath = parameterSet.get("outputPath", "../../outputs/output.txt"); -// std::string outputPath = parameterSet.get("outputPath", "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt"); - std::string outputPath = parameterSet.get("outputPath", "/home/klaus/Desktop/DUNE/dune-microstructure/outputs"); -// std::string MatlabPath = parameterSet.get("MatlabPath", "/home/klaus/Desktop/DUNE/dune-microstructure/Matlab-Programs"); -// std::string outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt"; - std::fstream log; - log.open(outputPath + "/output.txt" ,std::ios::out); - - std::cout << "outputPath:" << outputPath << std::endl; - -// parameterSet.report(log); // short Alternativ - - constexpr int dim = 3; - constexpr int dimWorld = 3; - - /////////////////////////////////// - // Get Parameters/Data - /////////////////////////////////// - double gamma = parameterSet.get<double>("gamma",3.0); // ratio dimension reduction to homogenization - double alpha = parameterSet.get<double>("alpha", 2.0); - double theta = parameterSet.get<double>("theta",1.0/4.0); - /////////////////////////////////// - // Get Material Parameters - /////////////////////////////////// - std::string imp = parameterSet.get<std::string>("material_prestrain_imp", "analytical_Example"); - double beta = parameterSet.get<double>("beta",2.0); - double mu1 = parameterSet.get<double>("mu1",10.0);; - double mu2 = beta*mu1; - double lambda1 = parameterSet.get<double>("lambda1",0.0);; - double lambda2 = beta*lambda1; - - // Plate geometry settings - double width = parameterSet.get<double>("width", 1.0); //geometry cell, cross section - // double len = parameterSet.get<double>("len", 10.0); //length - // double height = parameterSet.get<double>("h", 0.1); //rod thickness - // double eps = parameterSet.get<double>("eps", 0.1); //size of perioticity cell - - /////////////////////////////////// - // Get Prestrain/Parameters - /////////////////////////////////// -// unsigned int prestraintype = parameterSet.get<unsigned int>("prestrainType", "analytical_Example"); //OLD -// std::string prestraintype = parameterSet.get<std::string>("prestrainType", "analytical_Example"); -// double rho1 = parameterSet.get<double>("rho1", 1.0); -// double rho2 = alpha*rho1; -// auto prestrainImp = PrestrainImp(rho1, rho2, theta, width); -// auto B_Term = prestrainImp.getPrestrain(prestraintype); - - - - log << "----- Input Parameters -----: " << std::endl; -// log << "prestrain imp: " << prestraintype << "\nrho1 = " << rho1 << "\nrho2 = " << rho2 << std::endl; - log << "alpha: " << alpha << std::endl; - log << "gamma: " << gamma << std::endl; - log << "theta: " << theta << std::endl; - log << "beta: " << beta << std::endl; - log << "material parameters: " << std::endl; - log << "mu1: " << mu1 << "\nmu2: " << mu2 << std::endl; - log << "lambda1: " << lambda1 <<"\nlambda2: " << lambda2 << std::endl; - log << "----------------------------: " << std::endl; - - /////////////////////////////////// - // Generate the grid - /////////////////////////////////// - - //Corrector Problem Domain: - unsigned int cellDomain = parameterSet.get<unsigned int>("cellDomain", 1); - // (shifted) Domain (-1/2,1/2)^3 - FieldVector<double,dim> lower({-1.0/2.0, -1.0/2.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0/2.0, 1.0/2.0, 1.0/2.0}); - if (cellDomain == 2) - { - // Domain : [0,1)^2 x (-1/2, 1/2) - FieldVector<double,dim> lower({0.0, 0.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0, 1.0, 1.0/2.0}); - } - - std::array<int,2> numLevels = parameterSet.get<std::array<int,2>>("numLevels", {1,3}); - - int levelCounter = 0; - - /////////////////////////////////// - // Create Data Storage - /////////////////////////////////// - // Storage:: #1 level #2 L2SymError #3 L2SymErrorOrder #4 L2Norm(sym) #5 L2Norm(sym-analytic) #6 L2Norm(phi_1) - std::vector<std::variant<std::string, size_t , double>> Storage_Error; - - // Storage:: #1 level #2 |q1_a-q1_c| #3 |q2_a-q2_c| #4 |q3_a-q3_c| #5 |b1_a-b1_c| #6 |b2_a-b2_c| #7 |b3_a-b3_c| - std::vector<std::variant<std::string, size_t , double>> Storage_Quantities; - - -// for(const size_t &level : numLevels) // explixite Angabe der levels.. {2,4} - for(size_t level = numLevels[0] ; level <= numLevels[1]; level++) // levels von bis.. [2,4] - { - std::cout << " ----------------------------------" << std::endl; - std::cout << "Level: " << level << std::endl; - std::cout << " ----------------------------------" << std::endl; - - Storage_Error.push_back(level); - Storage_Quantities.push_back(level); - std::array<int, dim> nElements = { (int)std::pow(2,level) , (int)std::pow(2,level) , (int)std::pow(2,level) }; - - std::cout << "Number of Elements in each direction: " << nElements << std::endl; - log << "Number of Elements in each direction: " << nElements << std::endl; - - using CellGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; - CellGridType grid_CE(lower,upper,nElements); - using GridView = CellGridType::LeafGridView; - const GridView gridView_CE = grid_CE.leafGridView(); - - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - using Domain = GridView::Codim<0>::Geometry::GlobalCoordinate; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - using VectorCT = BlockVector<FieldVector<double,1> >; - using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - - /////////////////////////////////// - // Create Lambda-Functions for material Parameters depending on microstructure - /////////////////////////////////// - - auto materialImp = IsotropicMaterialImp<dim>(); - auto muTerm = materialImp.getMu(parameterSet); - auto lambdaTerm = materialImp.getLambda(parameterSet); - - auto muGridF = Dune::Functions::makeGridViewFunction(muTerm, gridView_CE); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambdaTerm, gridView_CE); - auto lambdaLocal = localFunction(lambdaGridF); - - /////////////////////////////////// - // --- Choose Solver --- - // 1 : CG-Solver - // 2 : GMRES - // 3 : QR - /////////////////////////////////// - unsigned int Solvertype = parameterSet.get<unsigned int>("Solvertype", 1); - - // Print Options - bool print_debug = parameterSet.get<bool>("print_debug", false); - - - bool write_materialFunctions = parameterSet.get<bool>("write_materialFunctions", false); - bool write_prestrainFunctions = parameterSet.get<bool>("write_prestrainFunctions", false); - - - bool write_corrector_phi3 = parameterSet.get<bool>("write_corrector_phi3", false); - bool write_L2Error = parameterSet.get<bool>("write_L2Error", false); - bool write_IntegralMean = parameterSet.get<bool>("write_IntegralMean", false); - - ///////////////////////////////////////////////////////// - // Choose a finite element space for Cell Problem - ///////////////////////////////////////////////////////// - using namespace Functions::BasisFactory; - Functions::BasisFactory::Experimental::PeriodicIndexSet periodicIndices; - - // Don't do the following in real life: It has quadratic run-time in the number of vertices. - for (const auto& v1 : vertices(gridView_CE)) - for (const auto& v2 : vertices(gridView_CE)) - if (equivalent(v1.geometry().corner(0), v2.geometry().corner(0))) - { - periodicIndices.unifyIndexPair({gridView_CE.indexSet().index(v1)}, {gridView_CE.indexSet().index(v2)}); - } - - // First order periodic Lagrange-Basis - auto Basis_CE = makeBasis( - gridView_CE, - power<dim>( - Functions::BasisFactory::Experimental::periodic(lagrange<1>(), periodicIndices), - flatLexicographic())); - - log << "size of FiniteElementBasis: " << Basis_CE.size() << std::endl; - const int phiOffset = Basis_CE.size(); - - ///////////////////////////////////////////////////////// - // Data structures: Stiffness matrix and right hand side vectors - ///////////////////////////////////////////////////////// - VectorCT load_alpha1, load_alpha2, load_alpha3; - MatrixCT stiffnessMatrix_CE; - - bool set_IntegralZero = parameterSet.get<bool>("set_IntegralZero", true); - bool set_oneBasisFunction_Zero = false; - bool substract_integralMean = false; - if(set_IntegralZero) - { - set_oneBasisFunction_Zero = true; - substract_integralMean = true; - } - - ///////////////////////////////////////////////////////// - // Define "rhs"-functions - ///////////////////////////////////////////////////////// - Func2Tensor x3G_3 = [] (const Domain& x) { - return MatrixRT{{0.0, 1.0/sqrt(2)*x[2], 0.0}, {1.0/sqrt(2)*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_3neg = [x3G_3] (const Domain& x) {return -1.0*x3G_3(x);}; - - - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - 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, 1.0/sqrt(2), 0.0}, {1.0/sqrt(2), 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", "--"); - // log << basisContainer[0] << std::endl; - - - ////////////////////////////////////////////////////////////////////// - // Determine global indices of components for arbitrary (local) index - ////////////////////////////////////////////////////////////////////// - int arbitraryLeafIndex = parameterSet.get<unsigned int>("arbitraryLeafIndex", 0); // localIdx..assert Number < #ShapeFcts - int arbitraryElementNumber = parameterSet.get<unsigned int>("arbitraryElementNumber", 0); - - FieldVector<int,3> row; - row = arbitraryComponentwiseIndices(Basis_CE,arbitraryElementNumber,arbitraryLeafIndex); - if(print_debug) - printvector(std::cout, row, "row" , "--"); - - ///////////////////////////////////////////////////////// - // Assemble the system - ///////////////////////////////////////////////////////// - assembleCellStiffness(Basis_CE, muLocal, lambdaLocal, gamma, stiffnessMatrix_CE, parameterSet); - assembleCellLoad(Basis_CE, muLocal, lambdaLocal,gamma, load_alpha3 ,x3G_3neg); // only third corrector is needed - // printmatrix(std::cout, stiffnessMatrix_CE, "StiffnessMatrix", "--"); - // printvector(std::cout, load_alpha1, "load_alpha1", "--"); - - - - // set one basis-function to zero - if(set_oneBasisFunction_Zero) - { - setOneBaseFunctionToZero(Basis_CE, stiffnessMatrix_CE, load_alpha3, parameterSet); - } - - //////////////////////////////////////////////////// - // Compute solution - //////////////////////////////////////////////////// - VectorCT x_3 = load_alpha3; - - if (Solvertype == 1) // CG - SOLVER - { - std::cout << "------------ CG - Solver ------------" << std::endl; - MatrixAdapter<MatrixCT, VectorCT, VectorCT> op(stiffnessMatrix_CE); - - - - // Sequential incomplete LU decomposition as the preconditioner - SeqILU<MatrixCT, VectorCT, VectorCT> ilu0(stiffnessMatrix_CE,1.0); - int iter = parameterSet.get<double>("iterations_CG", 999); - // Preconditioned conjugate-gradient solver - CGSolver<VectorCT> solver(op, - ilu0, //NULL, - 1e-8, // desired residual reduction factorlack - iter, // maximum number of iterations - 2); // verbosity of the solver - InverseOperatorResult statistics; -// std::cout << "solve linear system for x_1.\n"; -// solver.apply(x_1, load_alpha1, statistics); -// std::cout << "solve linear system for x_2.\n"; -// solver.apply(x_2, load_alpha2, statistics); - std::cout << "solve linear system for x_3.\n"; - solver.apply(x_3, load_alpha3, statistics); - log << "Solver-type used: " <<" CG-Solver" << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - - else if (Solvertype ==2) // GMRES - SOLVER - { - - std::cout << "------------ GMRES - Solver ------------" << std::endl; - // Turn the matrix into a linear operator - MatrixAdapter<MatrixCT,VectorCT,VectorCT> stiffnessOperator(stiffnessMatrix_CE); - - // Fancy (but only) way to not have a preconditioner at all - Richardson<VectorCT,VectorCT> preconditioner(1.0); - - // Construct the iterative solver - RestartedGMResSolver<VectorCT> solver( - stiffnessOperator, // Operator to invert - preconditioner, // Preconditioner - 1e-10, // Desired residual reduction factor - 500, // Number of iterations between restarts, - // here: no restarting - 500, // Maximum number of iterations - 2); // Verbosity of the solver - - // Object storing some statistics about the solving process - InverseOperatorResult statistics; - - - solver.apply(x_3, load_alpha3, statistics); - log << "Solver-type used: " <<" GMRES-Solver" << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if ( Solvertype == 3)// QR - SOLVER - { - - std::cout << "------------ QR - Solver ------------" << std::endl; - log << "solveLinearSystems: We use QR solver.\n"; - //TODO install suitesparse - SPQR<MatrixCT> sPQR(stiffnessMatrix_CE); - sPQR.setVerbosity(1); - InverseOperatorResult statisticsQR; - - sPQR.apply(x_3, load_alpha3, statisticsQR); - log << "Solver-type used: " <<" QR-Solver" << std::endl; - } - - //////////////////////////////////////////////////////////////////////////////////// - // Extract phi_alpha & M_alpha coefficients - //////////////////////////////////////////////////////////////////////////////////// - VectorCT phi_3; - phi_3.resize(Basis_CE.size()); - phi_3 = 0; - - for(size_t i=0; i<Basis_CE.size(); i++) - { - - phi_3[i] = x_3[i]; - } - - FieldVector<double,3> m_1, m_2, m_3; - - for(size_t i=0; i<3; i++) - { - m_3[i] = x_3[phiOffset+i]; - } - // 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_3 += m_3[i]*basisContainer[i]; - } - - std::cout << "--- plot corrector-Matrices M_alpha --- " << std::endl; -// printmatrix(std::cout, M_3, "Corrector-Matrix M_3", "--"); - log << "---------- OUTPUT ----------" << std::endl; - log << " --------------------" << std::endl; - log << "Corrector-Matrix M_3: \n" << M_3 << std::endl; - log << " --------------------" << std::endl; - - //////////////////////////////////////////////////////////////////////////// - // Substract Integral-mean - //////////////////////////////////////////////////////////////////////////// - using SolutionRange = FieldVector<double,dim>; - - if(substract_integralMean) - { - std::cout << " --- substracting integralMean --- " << std::endl; - subtractIntegralMean(Basis_CE, phi_3); - subtractIntegralMean(Basis_CE, x_3); - } - - //////////////////////////////////////////////////////////////////////////// - // Make a discrete function from the FE basis and the coefficient vector - //////////////////////////////////////////////////////////////////////////// // -// auto correctorFunction_3 = Functions::makeDiscreteGlobalBasisFunction<SolutionRange>( -// Basis_CE, -// phi_3); - - - ///////////////////////////////////////////////////////// - // Compute effective quantities: Elastic law & Prestrain - ///////////////////////////////////////////////////////// - VectorCT tmp1; - assembleCellLoad(Basis_CE, muLocal, lambdaLocal, gamma, tmp1 ,x3G_3); - double GGterm = 0.0; - GGterm = energy(Basis_CE, muLocal, lambdaLocal, x3G_3, x3G_3 ); - auto mu_gamma = (x_3*tmp1) + GGterm; - log << "mu_gamma=" << mu_gamma << std::endl; - - std::cout << "mu_gamma:" << mu_gamma << std::endl; - Storage_Quantities.push_back(mu_gamma); - - - levelCounter++; - } // Level-Loop End - - - log.close(); -} diff --git a/src/deprecated_code/cellsolver.parset b/src/deprecated_code/cellsolver.parset deleted file mode 100644 index 5f4db4625b202c12314d0fb10a988784b4c24b47..0000000000000000000000000000000000000000 --- a/src/deprecated_code/cellsolver.parset +++ /dev/null @@ -1,150 +0,0 @@ -# --- Parameter File as Input for 'Cell-Problem' -# -# NOTE: define variables without whitespaces in between! i.e. : gamma=1.0 instead of gamma = 1.0 -# since otherwise these cant be read from other Files! -# -------------------------------------------------------- - - -############################################# -# Choose Output-path for logfile -############################################# -### Remove/Comment this when running via Python-Script: -#outputPath=/home/stefan/DUNE/dune-microstructure/outputs -outputPath=/home/klaus/Desktop/Dune-Testing/dune-microstructure/outputs - - -### DEBUG Option: -print_debug = true - - -############################################# -# Cell Domain -############################################# -# Domain 1: (-1/2, 1/2)^3 , Domain 2 : [0,1)^2 x (-1/2, 1/2) -cellDomain=1 - -############################################# -# Grid parameters -############################################# -#---------------------------------------------------- -## numLevels : Number of Levels on which solution is computed. starting with a 2x2x2 cube mesh. -## {start,finish} computes on all grid from 2^(start) to 2^finish refinement -#---------------------------------------------------- - -numLevels= 2 2 -#numLevels = 0 0 # computes all levels from first to second entry -#numLevels = 2 2 # computes all levels from first to second entry -#numLevels = 1 3 # computes all levels from first to second entry -#numLevels = 4 4 # computes all levels from first to second entry -#numLevels = 5 5 # computes all levels from first to second entry -#numLevels = 6 6 # computes all levels from first to second entry -#numLevels = 1 6 - - - -######################################################################################## - -# --- Choose scale ratio gamma: -gamma=1.0 - - -############################################# -# Material / Prestrain parameters and ratios -############################################# - -#-- stiffness-ratio (ratio between material parameters mu1 & mu2 .... beta = 1.0 corresponds to homogeneous case) -beta=3.0 - -$--- strength of prestrain -rho1=1.0 - -#--- prestrain-contrast (ratio between prestrain parameters rho1 & rho2) -alpha=8.0 - - -#--- Lame-Parameters -mu1=80.0 -lambda1=80.0 - - -# better: pass material parameters as a vector -# Poisson ratio nu = 1/4 => lambda = 0.4*mu -#mu=1.2 1.2 1 -#lambda=0.48 0.48 0.4 -#rho=1.0 0 -mu=80 80 60 -lambda=80 80 25 - -#mu=1 -#lambda=4 - - - -# ---volume fraction (default value = 1.0/4.0) -theta=0.25 -#theta = 0.3 -#theta = 0.75 -#theta = 0.125 -#theta = 0.5 - - - -#--- choose composite-Implementation: -#geometryFunctionPath = /home/stefan/DUNE/dune-microstructure/geometries -geometryFunctionPath = /home/klaus/Desktop/Dune-Testing/dune-microstructure/geometries -material_prestrain_imp= "material_neukamm" #(Python-indicator-function with same name determines material phases) -#material_prestrain_imp= "two_phase_material_2" #(Python-indicator-function with same name determines material phases) -#material_prestrain_imp= "two_phase_material_3" #(Python-indicator-function with same name determines material phases) -#material_prestrain_imp= "parametrized_Laminate" -#material_prestrain_imp= "homogeneous" -#material_prestrain_imp= "analytical_Example" -#material_prestrain_imp="isotropic_bilayer" -#material_prestrain_imp= "circle_fiber" #TEST -#material_prestrain_imp= "matrix_material_circles" -#material_prestrain_imp= "matrix_material_squares" -#nF = 10 # Number of Fibers (default = 3) -#rF = 0.1 # Fiber-Radius (default = 0.5*(width/(2.0*nF)) //half of the max-fiber-radius mrF = (width/(2.0*nF)) ) - - -# --- (Optional output) write Material / prestrain / Corrector functions to .vtk-Files (default=false): -write_materialFunctions = true -write_prestrainFunctions = true # VTK norm of B , -write_VTK = true - - -# --- (Optional output) L2Error, compute integral mean: -#write_L2Error = true -#write_IntegralMean = true - - -############################################# -# Assembly options -############################################# -#set_IntegralZero = true -set_IntegralZero = false -#set_oneBasisFunction_Zero = true - -#arbitraryLocalIndex = 7 -#arbitraryElementNumber = 3 -#arbitraryLocalIndex = 0 -#arbitraryElementNumber = 0 -############################################# - - -############################################# -# Solver Type: #1: CG - SOLVER (default), #2: GMRES - SOLVER, #3: QR - SOLVER #4: UMFPACK - SOLVER -############################################# -Solvertype = 3 -Solver_verbosity = 0 #(default = 2) degree of information for solver output - - - - - -# --- Write corrector-coefficients to log-File (default=false): -#write_corrector_phi1 = false -#write_corrector_phi2 = false -#write_corrector_phi3 = false -#write_corrector_phi1 = true -#write_corrector_phi2 = true -#write_corrector_phi3 = true diff --git a/src/deprecated_code/cellsolver_backup.parset b/src/deprecated_code/cellsolver_backup.parset deleted file mode 100644 index 2e5651ba3159c48648724dffc37b0315265aad12..0000000000000000000000000000000000000000 --- a/src/deprecated_code/cellsolver_backup.parset +++ /dev/null @@ -1,151 +0,0 @@ -# --- Parameter File as Input for 'Cell-Problem' -# -# NOTE: define variables without whitespaces in between! i.e. : gamma=1.0 instead of gamma = 1.0 -# since otherwise these cant be read from other Files! -# -------------------------------------------------------- - - - - -#path for logfile -#outputPath = "../../outputs/output.txt" - - -### Remove/Comment this when running via Python-Script: -outputPath = "../../outputs" - - - -#outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt" -#outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs" - - -############################################# -# Cell Domain -############################################# -# Domain 1: (-1/2, 1/2)^3 , Domain 2 : [0,1)^2 x (-1/2, 1/2) - -cellDomain = 1 - -############################################# -# Grid parameters -############################################# - - -####################################################################### -## numLevels : Number of Levels on which solution is computed. starting with a 2x2x2 cube mesh. -## {start,finish} computes on all grid from 2^(start) to 2^finish refinement -######################################################################## - -#numLevels = 1 3 # computes all levels from first to second entry -numLevels = 3 3 # computes all levels from first to second entry -#numLevels = 1 6 - - -#Elements_Cell = 20 20 20 # number elements in each direction (y1 y2 x3) -#nElements_Cell = 30 30 30 -#nElements_Cell = 30 30 30 -#nElements_Cell = 50 50 50 -#nElements_Cell = 100 100 2 -#nElements_Cell = 100 100 100 // does not work -#nElements_Cell = 10 10 10 -#nElements_Cell = 2 2 2 -#nElements_Cell = 4 4 4 -#nElements_Cell = 8 8 8 -#nElements_Cell = 16 16 16 -#nElements_Cell = 32 32 32 -#nElements_Cell = 64 64 64 - - -#gamma=50.0 -gamma=1.0 -#gamma=2.5 - -############################################# -# Material parameters -############################################# -beta = 2.0 # ratio between material parameters mu1 & mu2 .... beta = 1.0 corresponds to homogeneous case - -mu1=1.0 -lambda1=0.0 -#lambda1 = 20.0 -#lambda1 = 20.0 -#lambda1 = 5.0 -#mu1=1000.0 - - -rho1 = 1.0 -#alpha = 5.0 # ratio between prestrain parameters rho1 & rho2 -alpha = 2.0 # ratio between prestrain parameters rho1 & rho2 - - -theta = 0.125 -#theta = 0.25 -#theta = 0.3 # volume fraction #default = 1.0/4.0 -#theta = 0.25 # volume fraction -#theta = 0.75 # volume fraction - -#### material_implementation("analytical_Example") ? - - - - -#material_prestrain_imp ="isotropic_bilayer" -#### material_implementation("analytical_Example") ? - -material_prestrain_imp= "analytical_Example" -#material_prestrain_imp ="isotropic_bilayer" - - -#material_prestrain_imp= "circle_fiber" #TEST -write_prestrainFunctions = true # VTK norm of B , - - - - - -# Prestrain Types: - -#1 Isotropic Pressure -# Func2Tensor B1_ = [this] (const Domain& x) { // ISOTROPIC PRESSURE -# if (abs(x[0]) > (theta/2) && x[2] > 0) -# return MatrixRT{{p1, 0.0 , 0.0}, {0.0, p1, 0.0}, {0.0, 0.0, p1}}; -# if (abs(x[0]) < (theta/2) && x[2] < 0) -# return MatrixRT{{p2, 0.0 , 0.0}, {0.0, p2, 0.0}, {0.0, 0.0, p2}}; -# else -# return MatrixRT{{0.0, 0.0 , 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; -# }; - - -############################################# -# Assembly options -############################################# - -set_IntegralZero = true -#set_IntegralZero = false - -#arbitraryLocalIndex = 7 -#arbitraryElementNumber = 3 - -#arbitraryLocalIndex = 0 -#arbitraryElementNumber = 0 - - -############################################# -# Solver Type - -Solvertype = 1 - -#write_corrector_phi1 = false -#write_corrector_phi2 = false -#write_corrector_phi3 = false -#write_corrector_phi1 = true -#write_corrector_phi2 = true -#write_corrector_phi3 = true - -write_L2Error = true -#write_IntegralMean = true - - -############################################# -# Define Analytic Solutions diff --git a/src/deprecated_code/computeMuGamma_backup.parset b/src/deprecated_code/computeMuGamma_backup.parset deleted file mode 100644 index 9b17b4f68f2007731aeb74849362d1a3d42c07fd..0000000000000000000000000000000000000000 --- a/src/deprecated_code/computeMuGamma_backup.parset +++ /dev/null @@ -1,113 +0,0 @@ -# --- Parameter File as Input for 'Compute_MuGamma' -# -# NOTE: define variables without whitespaces in between! i.e. : gamma=1.0 instead of gamma = 1.0 -# since otherwise these cant be read from other Files! -# -------------------------------------------------------- - - - - -#path for logfile -#outputPath = "../../outputs/output.txt" -#outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs/output.txt" -#outputPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs" - -############################################# -# Debug Output -############################################# - -#print_debug = true #default = false - - - - - -############################################# -# Grid parameters -############################################# - - -nElements = 32 32 - -gamma=0.7559719438877756 - - -############################################# -# Material parameters -############################################# - -write_materialFunctions = true # VTK mu-functions , lambda-functions - -beta=10.0 - -mu1=1.0 - - -#lambda1=10.0 - - -#### material_implementation("analytical_Example") ? - -material_prestrain_imp= "analytical_Example" -#material_prestrain_imp ="isotropic_bilayer" - - -#material_prestrain_imp= "circle_fiber" #TEST -#material_prestrain_imp= "square_fiber" #TEST - -############################################# -# Prestrain parameters -############################################# - -write_prestrainFunctions = true # VTK norm of B , - - -rho1=1.0 -alpha=10.0 - -theta=0.125 - -#theta = 0.3 # volume fraction #default = 1.0/4.0 -#theta = 0.25 # volume fraction -#theta = 0.75 # volume fraction - - - -------------Matrix Material -------------- -#material_prestrain_imp ="matrix_material_circles" -#material_prestrain_imp ="matrix_material_squares" - -nF = 8 #number of Fibers (in each Layer) -#rF = 0.05 #Fiber radius max-fiber-radius = (width/(2.0*nF) ------------------------------------------- - -width = 1.0 -height = 1.0 - - - - - -############################################# -# Solver Type -############################################# -# 1: CG-Solver # 2: GMRES # 3: QR - -Solvertype = 1 - - - - -############################################# -# Define Analytic Solutions -############################################# - -#b1 = (-(theta/4.0)*mu1*mu2)/(theta*mu1+(1.0-theta)*mu2) - - - - - - - - diff --git a/src/deprecated_code/elasticityTensor-globalFunctionVersion/Cell-Problem-New.cc b/src/deprecated_code/elasticityTensor-globalFunctionVersion/Cell-Problem-New.cc deleted file mode 100644 index 09859eb5c17e8a6959c30475ea8b4fbdf8c776b8..0000000000000000000000000000000000000000 --- a/src/deprecated_code/elasticityTensor-globalFunctionVersion/Cell-Problem-New.cc +++ /dev/null @@ -1,766 +0,0 @@ -#include <config.h> -#include <array> -#include <vector> -#include <fstream> - -#include <iostream> -#include <dune/common/indices.hh> -#include <dune/common/bitsetvector.hh> -#include <dune/common/parametertree.hh> -#include <dune/common/parametertreeparser.hh> -#include <dune/common/float_cmp.hh> -#include <dune/common/math.hh> - - -#include <dune/geometry/quadraturerules.hh> - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -// #include <dune/grid/utility/structuredgridfactory.hh> //TEST -#include <dune/grid/io/file/vtk/subsamplingvtkwriter.hh> - -#include <dune/istl/matrix.hh> -#include <dune/istl/bcrsmatrix.hh> -#include <dune/istl/multitypeblockmatrix.hh> -#include <dune/istl/multitypeblockvector.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/istl/solvers.hh> -#include <dune/istl/spqr.hh> -#include <dune/istl/preconditioners.hh> -#include <dune/istl/io.hh> - -#include <dune/functions/functionspacebases/interpolate.hh> -#include <dune/functions/backends/istlvectorbackend.hh> -#include <dune/functions/functionspacebases/powerbasis.hh> -#include <dune/functions/functionspacebases/compositebasis.hh> -#include <dune/functions/functionspacebases/lagrangebasis.hh> -#include <dune/functions/functionspacebases/periodicbasis.hh> -#include <dune/functions/functionspacebases/subspacebasis.hh> -#include <dune/functions/functionspacebases/boundarydofs.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> -#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh> - -#include <dune/common/fvector.hh> -#include <dune/common/fmatrix.hh> - -#include <dune/microstructure/prestrain_material_geometry.hh> -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/vtk_filler.hh> //TEST -#include <dune/microstructure/CorrectorComputer.hh> -#include <dune/microstructure/EffectiveQuantitiesComputer.hh> -#include <dune/microstructure/prestrainedMaterial.hh> - -#include <dune/solvers/solvers/umfpacksolver.hh> //TEST -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number - -// #include <dune/fufem/discretizationerror.hh> -#include <dune/fufem/dunepython.hh> -#include <python2.7/Python.h> - -// #include <boost/multiprecision/cpp_dec_float.hpp> -#include <any> -#include <variant> -#include <string> -#include <iomanip> // needed when working with relative paths e.g. from python-scripts - -using namespace Dune; -using namespace MatrixOperations; - -////////////////////////////////////////////////////////////////////// -// Helper functions for Table-Output -////////////////////////////////////////////////////////////////////// -/*! Center-aligns string within a field of width w. Pads with blank spaces - to enforce alignment. */ -std::string center(const std::string s, const int w) { - std::stringstream ss, spaces; - int padding = w - s.size(); // count excess room to pad - for(int i=0; i<padding/2; ++i) - spaces << " "; - ss << spaces.str() << s << spaces.str(); // format with padding - if(padding>0 && padding%2!=0) // if odd #, add 1 space - ss << " "; - return ss.str(); -} - -/* Convert double to string with specified number of places after the decimal - and left padding. */ -template<class type> -std::string prd(const type x, const int decDigits, const int width) { - std::stringstream ss; -// ss << std::fixed << std::right; - ss << std::scientific << std::right; // Use scientific Output! - ss.fill(' '); // fill space around displayed # - ss.width(width); // set width around displayed # - ss.precision(decDigits); // set # places after decimal - ss << x; - return ss.str(); -} - -////////////////////////////////////////////////// -// Infrastructure for handling periodicity -////////////////////////////////////////////////// -// Check whether two points are equal on R/Z x R/Z x R -auto equivalent = [](const FieldVector<double,3>& x, const FieldVector<double,3>& y) - { - return ( (FloatCmp::eq(x[0],y[0]) or FloatCmp::eq(x[0]+1,y[0]) or FloatCmp::eq(x[0]-1,y[0])) - and (FloatCmp::eq(x[1],y[1]) or FloatCmp::eq(x[1]+1,y[1]) or FloatCmp::eq(x[1]-1,y[1])) - and (FloatCmp::eq(x[2],y[2])) - ); - }; - - - -// // a function: -// int half(int x, int y) {return x/2+y/2;} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -int main(int argc, char *argv[]) -{ - MPIHelper::instance(argc, argv); - - Dune::Timer globalTimer; - - ParameterTree parameterSet; - if (argc < 2) - ParameterTreeParser::readINITree("../../inputs/cellsolver.parset", parameterSet); - else - { - ParameterTreeParser::readINITree(argv[1], parameterSet); - ParameterTreeParser::readOptions(argc, argv, parameterSet); - } - - //--- Output setter - std::string outputPath = parameterSet.get("outputPath", "../../outputs"); - - //--- setup Log-File - std::fstream log; - log.open(outputPath + "/output.txt" ,std::ios::out); - - std::cout << "outputPath:" << outputPath << std::endl; - -// parameterSet.report(log); // short Alternativ - - //--- Get Path for Material/Geometry functions - std::string geometryFunctionPath = parameterSet.get<std::string>("geometryFunctionPath"); - //--- Start Python interpreter - Python::start(); - Python::Reference main = Python::import("__main__"); - Python::run("import math"); - Python::runStream() - << std::endl << "import sys" - << std::endl << "sys.path.append('" << geometryFunctionPath << "')" - << std::endl; - - - constexpr int dim = 3; - constexpr int dimWorld = 3; - - // Debug/Print Options - bool print_debug = parameterSet.get<bool>("print_debug", false); - - // VTK-write options - bool write_materialFunctions = parameterSet.get<bool>("write_materialFunctions", false); - bool write_prestrainFunctions = parameterSet.get<bool>("write_prestrainFunctions", false); - - - - - /////////////////////////////////// - // Get Parameters/Data - /////////////////////////////////// - double gamma = parameterSet.get<double>("gamma",1.0); // ratio dimension reduction to homogenization - double alpha = parameterSet.get<double>("alpha", 2.0); - double theta = parameterSet.get<double>("theta",1.0/4.0); - /////////////////////////////////// - // Get Material Parameters - /////////////////////////////////// - std::string imp = parameterSet.get<std::string>("material_prestrain_imp", "analytical_Example"); - log << "material_prestrain used: "<< imp << std::endl; - double beta = parameterSet.get<double>("beta",2.0); - double mu1 = parameterSet.get<double>("mu1",1.0);; - double mu2 = beta*mu1; - double lambda1 = parameterSet.get<double>("lambda1",0.0);; - double lambda2 = beta*lambda1; - - - if(imp == "material_neukamm") - { - std::cout <<"mu: " << parameterSet.get<std::array<double,3>>("mu", {1.0,3.0,2.0}) << std::endl; - std::cout <<"lambda: " << parameterSet.get<std::array<double,3>>("lambda", {1.0,3.0,2.0}) << std::endl; - } - else - { - std::cout <<"mu: " << parameterSet.get<double>("mu1",1.0) << std::endl; - std::cout <<"lambda: " << parameterSet.get<double>("lambda1",0.0) << std::endl; - } - - /////////////////////////////////// - // Get Prestrain/Parameters - /////////////////////////////////// - auto prestrainImp = PrestrainImp<dim>(); //NEW - auto B_Term = prestrainImp.getPrestrain(parameterSet); - - log << "----- Input Parameters -----: " << std::endl; - log << "alpha: " << alpha << std::endl; - log << "gamma: " << gamma << std::endl; - log << "theta: " << theta << std::endl; - log << "beta: " << beta << std::endl; - log << "material parameters: " << std::endl; - log << "mu1: " << mu1 << "\nmu2: " << mu2 << std::endl; - log << "lambda1: " << lambda1 <<"\nlambda2: " << lambda2 << std::endl; - log << "----------------------------: " << std::endl; - - /////////////////////////////////// - // Generate the grid - /////////////////////////////////// - // --- Corrector Problem Domain (-1/2,1/2)^3: - FieldVector<double,dim> lower({-1.0/2.0, -1.0/2.0, -1.0/2.0}); - FieldVector<double,dim> upper({1.0/2.0, 1.0/2.0, 1.0/2.0}); - - std::array<int,2> numLevels = parameterSet.get<std::array<int,2>>("numLevels", {1,3}); - int levelCounter = 0; - - - /////////////////////////////////// - // Create Data Storage - /////////////////////////////////// - //--- Storage:: #1 level #2 L2SymError #3 L2SymErrorOrder #4 L2Norm(sym) #5 L2Norm(sym-analytic) #6 L2Norm(phi_1) - std::vector<std::variant<std::string, size_t , double>> Storage_Error; - //--- Storage:: | level | q1 | q2 | q3 | q12 | q23 | b1 | b2 | b3 | - std::vector<std::variant<std::string, size_t , double>> Storage_Quantities; - - // for(const size_t &level : numLevels) // explixite Angabe der levels.. {2,4} - for(size_t level = numLevels[0] ; level <= numLevels[1]; level++) // levels von bis.. [2,4] - { - std::cout << " ----------------------------------" << std::endl; - std::cout << "GridLevel: " << level << std::endl; - std::cout << " ----------------------------------" << std::endl; - - Storage_Error.push_back(level); - Storage_Quantities.push_back(level); - std::array<int, dim> nElements = {(int)std::pow(2,level) ,(int)std::pow(2,level) ,(int)std::pow(2,level)}; - std::cout << "Number of Grid-Elements in each direction: " << nElements << std::endl; - log << "Number of Grid-Elements in each direction: " << nElements << std::endl; - - using CellGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; - CellGridType grid_CE(lower,upper,nElements); - using GridView = CellGridType::LeafGridView; - const GridView gridView_CE = grid_CE.leafGridView(); - if(print_debug) - std::cout << "Host grid has " << gridView_CE.size(dim) << " vertices." << std::endl; - - // //not needed - using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - using Domain = GridView::Codim<0>::Geometry::GlobalCoordinate; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - // using Func2Tensor = std::function< MatrixRT(const Domain&) >; - // using VectorCT = BlockVector<FieldVector<double,1> >; - // using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - - /////////////////////////////////// - // Create Lambda-Functions for material Parameters depending on microstructure - /////////////////////////////////// - auto materialImp = IsotropicMaterialImp<dim>(); - auto muTerm = materialImp.getMu(parameterSet); - auto lambdaTerm = materialImp.getLambda(parameterSet); - - auto muGridF = Dune::Functions::makeGridViewFunction(muTerm, gridView_CE); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambdaTerm, gridView_CE); - auto lambdaLocal = localFunction(lambdaGridF); - - - //--- Choose a finite element space for Cell Problem - using namespace Functions::BasisFactory; - Functions::BasisFactory::Experimental::PeriodicIndexSet periodicIndices; - - //--- get PeriodicIndices for periodicBasis (Don't do the following in real life: It has quadratic run-time in the number of vertices.) - for (const auto& v1 : vertices(gridView_CE)) - for (const auto& v2 : vertices(gridView_CE)) - if (equivalent(v1.geometry().corner(0), v2.geometry().corner(0))) - { - periodicIndices.unifyIndexPair({gridView_CE.indexSet().index(v1)}, {gridView_CE.indexSet().index(v2)}); - } - - //--- setup first order periodic Lagrange-Basis - auto Basis_CE = makeBasis( - gridView_CE, - power<dim>( // eig dimworld?!?! - Functions::BasisFactory::Experimental::periodic(lagrange<1>(), periodicIndices), - flatLexicographic() - //blockedInterleaved() // Not Implemented - )); - if(print_debug) - std::cout << "power<periodic> basis has " << Basis_CE.dimension() << " degrees of freedom" << std::endl; - - - - - - //TEST - //Read from Parset... - // int Phases = parameterSet.get<int>("Phases", 3); - - - std::string materialFunctionName = parameterSet.get<std::string>("materialFunction", "material"); - Python::Module module = Python::import(materialFunctionName); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); - // Func2Tensor indicatorFunction = Python::make_function<double>(module.get("f")); - // auto materialFunction_ = Python::make_function<double>(module.get("f")); - // auto materialFunction_ = Python::make_function<double>(module.get("f")); - auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - - int Phases; - module.get("Phases").toC<int>(Phases); - std::cout << "Number of Phases used:" << Phases << std::endl; - - - // std::cout << typeid(mu_).name() << '\n'; - - - //---- Get mu/lambda values (for isotropic material) from Material-file - FieldVector<double,3> mu_(0); - module.get("mu_").toC<FieldVector<double,3>>(mu_); - printvector(std::cout, mu_ , "mu_", "--"); - FieldVector<double,3> lambda_(0); - module.get("lambda_").toC<FieldVector<double,3>>(lambda_); - printvector(std::cout, lambda_ , "lambda_", "--"); - - - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // TESTING PRESTRAINEDMATERIAL.HH: - using Func2TensorParam = std::function< MatrixRT(const MatrixRT& ,const Domain&) >; - - auto material_ = prestrainedMaterial(gridView_CE,parameterSet); - // Func2Tensor elasticityTensor = material_.getElasticityTensor(); - // auto elasticityTensor = material_.getElasticityTensor(); - // Func2TensorParam elasticityTensor_ = *material_.getElasticityTensor(); - auto elasticityTensor_ = material_.getElasticityTensor(); - - Func2TensorParam TestTensor = Python::make_function<MatrixRT>(module.get("H")); - - // std::cout << "decltype(elasticityTensor_) " << decltype(elasticityTensor_) << std::endl; - - - std::cout <<"typeid(elasticityTensor).name() :" << typeid(elasticityTensor_).name() << '\n'; - std::cout << "typeid(TestTensor).name() :" << typeid(TestTensor).name() << '\n'; - - using MatrixFunc = std::function< MatrixRT(const MatrixRT&) >; - // std::cout << "Import NOW:" << std::endl; - // MatrixFunc symTest = Python::make_function<MatrixRT>(module.get("sym")); - - // using MatrixDomainFunc = std::function< MatrixRT(const MatrixRT&,const Domain&)>; - // // MatrixFunc elasticityTensor = Python::make_function<MatrixRT>(module.get("L")); - - // auto elasticityTensorGVF = Dune::Functions::makeGridViewFunction(elasticityTensor , Basis_CE.gridView()); - // auto localElasticityTensor = localFunction(elasticityTensorGVF); - - // Func2Tensor forceTerm = [] (const Domain& x) { - // return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - // }; - - // auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, Basis_CE.gridView()); - // auto loadFunctional = localFunction(loadGVF); - - MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - // auto xu = symTest(G1_); - // std::cout << "TEST NOW:" << std::endl; - // printmatrix(std::cout, symTest(G1_), "symTest(G1_)", "--"); - - // auto TestTensorGVF = Dune::Functions::makeGridViewFunction(TestTensor , Basis_CE.gridView()); - // auto localTestTensor = localFunction(TestTensorGVF ); - - - // printmatrix(std::cout, elasticityTensor(G1_), "elasticityTensor(G1_)", "--"); - // auto temp = elasticityTensor(G1_); - - - - for (const auto& element : elements(Basis_CE.gridView())) - { - - int orderQR = 2; - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - // std::cout << "quadPos : " << quadPos << std::endl; - auto temp = TestTensor(G1_, element.geometry().global(quadPos)); - auto temp2 = elasticityTensor_(G1_, element.geometry().global(quadPos)); - // std::cout << "material_.applyElasticityTensor:" << std::endl; - auto tmp3 = material_.applyElasticityTensor(G1_, element.geometry().global(quadPos)); - // printmatrix(std::cout, tmp3, "tmp3", "--"); - } - } - - - - // for (auto&& vertex : vertices(gridView_CE)) - // { - // std::cout << "vertex.geometry().corner(0):" << vertex.geometry().corner(0)<< std::endl; - // auto tmp = vertex.geometry().corner(0); - // auto temp = elasticityTensor(tmp); - // // std::cout << "materialFunction_(vertex.geometry().corner(0))", materialFunction_(vertex.geometry().corner(0)) << std::endl; - // // printmatrix(std::cout, localElasticityTensor(G1_,tmp), "localElasticityTensor(vertex.geometry().corner(0))", "--"); - // } - - - - // std::function<int(int,int)> fn1 = half; - // std::cout << "fn1(60,20): " << fn1(60,20) << '\n'; - - - // std::cout << typeid(elasticityTensorGVF).name() << '\n'; - // std::cout << typeid(localElasticityTensor).name() << '\n'; - - - // ParameterTree parameterSet_2; - // ParameterTreeParser::readINITree(geometryFunctionPath + "/"+ materialFunctionName + ".py", parameterSet_2); - - // auto lu = parameterSet_2.get<FieldVector<double,3>>("lu", {1.0,3.0,2.0}); - // std::cout <<"lu[1]: " << lu[1]<< std::endl; - // std::cout <<"lu: " << parameterSet_2.get<std::array<double,3>>("lu", {1.0,3.0,2.0}) << std::endl; - - // auto mU_ = module.evaluate(parameterSet_2.get<std::string>("lu", "[1,2,3]")); - // std::cout << "typeid(mU_).name()" << typeid(mU_.operator()()).name() << '\n'; - - - // for (auto&& vertex : vertices(gridView_CE)) - // { - // std::cout << "vertex.geometry().corner(0):" << vertex.geometry().corner(0)<< std::endl; - // // std::cout << "materialFunction_(vertex.geometry().corner(0))", materialFunction_(vertex.geometry().corner(0)) << std::endl; - // printvector(std::cout, materialFunction_(vertex.geometry().corner(0)), "materialFunction_(vertex.geometry().corner(0))", "--"); - // } - // std::cout << "materialFunction_({0.0,0.0,0.0})", materialFunction_({0.0,0.0,0.0}) << std::endl; - - - - // -------------------------------------------------------------- - - //TODO// Phasen anhand von Mu bestimmen? - //TODO: DUNE_THROW(Exception, "Inconsistent choice of interpolation method"); if number of Phases != mu/lambda parameters - - //FÜR L GARNICHT NÖTIG DENN RÜCKGABETYPE IS IMMER MATRIXRT!?!: - // BEi materialfunction (isotopic) reicht auch FieldVector<double,2> für lambda/mu - - // switch (Phases) - // { - // case 1: //homogeneous material - // { - // std::cout << "Phase - 1" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // case 2: - // { - // std::cout << "Phase - 1" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // case 3: - // { - // std::cout << "Phase - 3" << std::endl; - // auto materialFunction_ = Python::make_function<FieldVector<double,2>>(module.get("f")); - // break; - // } - // } - - - // switch (Phases) - // { - // case 1: //homogeneous material - // { - // std::cout << "Phases - 1" << std::endl; - // std::array<double,1> mu_ = parameterSet.get<std::array<double,1>>("mu", {1.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_] (const Domain& x) {return mu_;}; - // break; - // } - // case 2: - // { - // std::cout << "Phases - 2" << std::endl; - // std::array<double,2> mu_ = parameterSet.get<std::array<double,2>>("mu", {1.0,3.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_,indicatorFunction] (const Domain& x) - // { - // if (indicatorFunction(x) == 1) - // return mu_[0]; - // else - // return mu_[1]; - // }; - // break; - // } - // case 3: - // { - // std::cout << "Phases - 3" << std::endl; - // std::array<double,3> mu_ = parameterSet.get<std::array<double,3>>("mu", {1.0,3.0, 5.0}); - // Python::Module module = Python::import(materialFunction); - // auto indicatorFunction = Python::make_function<double>(module.get("f")); // get indicator function - // auto muTerm = [mu_,indicatorFunction] (const Domain& x) - // { - // if (indicatorFunction(x) == 1) - // return mu_[0]; - // else if (indicatorFunction(x) == 2) - // return mu_[1]; - // else - // return mu_[2]; - // }; - // break; - // } - // } - - - - - //TEST -// std::cout << "Test crossSectionDirectionScaling:" << std::endl; -/* - MatrixRT T {{1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}, {1.0, 1.0, 1.0}}; - printmatrix(std::cout, T, "Matrix T", "--"); - - auto ST = crossSectionDirectionScaling((1.0/5.0),T); - printmatrix(std::cout, ST, "scaled Matrix T", "--");*/ - - //TEST -// auto QuadraticForm = [] (const double mu, const double lambda, const MatrixRT& M) { -// -// return lambda*std::pow(trace(M),2) + 2*mu*pow(norm(sym(M)),2); -// }; - - - //------------------------------------------------------------------------------------------------ - //--- compute Correctors - // auto correctorComputer = CorrectorComputer(Basis_CE, muTerm, lambdaTerm, gamma, log, parameterSet); - auto correctorComputer = CorrectorComputer(Basis_CE, material_, muTerm, lambdaTerm, gamma, log, parameterSet); - correctorComputer.solve(); - - - -////////////////////////////////////////////////// - - - //--- check Correctors (options): - if(parameterSet.get<bool>("write_L2Error", false)) - correctorComputer.computeNorms(); - if(parameterSet.get<bool>("write_VTK", false)) - correctorComputer.writeCorrectorsVTK(level); - //--- additional Test: check orthogonality (75) from paper: - if(parameterSet.get<bool>("write_checkOrthogonality", false)) - correctorComputer.check_Orthogonality(); - //--- Check symmetry of stiffness matrix - if(print_debug) - correctorComputer.checkSymmetry(); - - - //--- compute effective quantities - auto effectiveQuantitiesComputer = EffectiveQuantitiesComputer(correctorComputer,B_Term,material_); - effectiveQuantitiesComputer.computeEffectiveQuantities(); - - - } - /* - - //--- Test:: Compute Qeff without using the orthogonality (75)... - // only really makes a difference whenever the orthogonality is not satisfied! - // std::cout << "----------computeFullQ-----------"<< std::endl; //TEST - // effectiveQuantitiesComputer.computeFullQ(); - - //--- get effective quantities - auto Qeff = effectiveQuantitiesComputer.getQeff(); - auto Beff = effectiveQuantitiesComputer.getBeff(); - printmatrix(std::cout, Qeff, "Matrix Qeff", "--"); - printvector(std::cout, Beff, "Beff", "--"); - - //--- write effective quantities to matlab folder (for symbolic minimization) - if(parameterSet.get<bool>("write_toMATLAB", false)) - effectiveQuantitiesComputer.writeToMatlab(outputPath); - - std::cout.precision(10); - std::cout<< "q1 : " << Qeff[0][0] << std::endl; - std::cout<< "q2 : " << Qeff[1][1] << std::endl; - std::cout<< "q3 : " << std::fixed << Qeff[2][2] << std::endl; - std::cout<< std::fixed << std::setprecision(6) << "q_onetwo=" << Qeff[0][1] << std::endl; - // ------------------------------------------- - - - //TEST - // Func2Tensor x3G_1 = [] (const Domain& x) { - // return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - // }; - - // double energy = effectiveQuantitiesComputer.energySP(x3G_1,x3G_1); - // std::cout << "energy:" << energy << std::endl; - - Storage_Quantities.push_back(Qeff[0][0] ); - Storage_Quantities.push_back(Qeff[1][1] ); - Storage_Quantities.push_back(Qeff[2][2] ); - Storage_Quantities.push_back(Qeff[0][1] ); - Storage_Quantities.push_back(Qeff[1][2] ); - Storage_Quantities.push_back(Beff[0]); - Storage_Quantities.push_back(Beff[1]); - Storage_Quantities.push_back(Beff[2]); - - log << "size of FiniteElementBasis: " << Basis_CE.size() << std::endl; - log << "q1=" << Qeff[0][0] << std::endl; - log << "q2=" << Qeff[1][1] << std::endl; - log << "q3=" << Qeff[2][2] << std::endl; - log << "q12=" << Qeff[0][1] << std::endl; - log << "q23=" << Qeff[1][2] << std::endl; - log << std::fixed << std::setprecision(6) << "q_onetwo=" << Qeff[0][1] << std::endl; - log << "b1=" << Beff[0] << std::endl; - log << "b2=" << Beff[1] << std::endl; - log << "b3=" << Beff[2] << std::endl; - log << "mu_gamma=" << Qeff[2][2] << std::endl; // added for Python-Script - - - - - if (write_materialFunctions) - { - using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); - VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); - - using GridViewVTK = VTKGridType::LeafGridView; - const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - - auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); - auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - - std::vector<double> mu_CoeffP0; - Functions::interpolate(scalarP0FeBasis, mu_CoeffP0, muTerm); - auto mu_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, mu_CoeffP0); - - std::vector<double> mu_CoeffP1; - Functions::interpolate(scalarP1FeBasis, mu_CoeffP1, muTerm); - auto mu_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, mu_CoeffP1); - - - std::vector<double> lambda_CoeffP0; - Functions::interpolate(scalarP0FeBasis, lambda_CoeffP0, lambdaTerm); - auto lambda_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, lambda_CoeffP0); - - std::vector<double> lambda_CoeffP1; - Functions::interpolate(scalarP1FeBasis, lambda_CoeffP1, lambdaTerm); - auto lambda_DGBF_P1 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP1FeBasis, lambda_CoeffP1); - - VTKWriter<GridView> MaterialVtkWriter(gridView_VTK); - - MaterialVtkWriter.addVertexData( - mu_DGBF_P1, - VTK::FieldInfo("mu_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - mu_DGBF_P0, - VTK::FieldInfo("mu_P0", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addVertexData( - lambda_DGBF_P1, - VTK::FieldInfo("lambda_P1", VTK::FieldInfo::Type::scalar, 1)); - MaterialVtkWriter.addCellData( - lambda_DGBF_P0, - VTK::FieldInfo("lambda_P0", VTK::FieldInfo::Type::scalar, 1)); - - MaterialVtkWriter.write(outputPath + "/MaterialFunctions-level"+ std::to_string(level) ); - std::cout << "wrote data to file:" + outputPath +"/MaterialFunctions-level" + std::to_string(level) << std::endl; - - } - - -// if (write_prestrainFunctions) -// { -// using VTKGridType = YaspGrid<dim, EquidistantOffsetCoordinates<double, dim> >; -// // VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{80,80,80}); -// // VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},{40,40,40}); -// VTKGridType grid_VTK({-1.0/2.0, -1.0/2.0, -1.0/2.0},{1.0/2.0, 1.0/2.0, 1.0/2.0},nElements); -// using GridViewVTK = VTKGridType::LeafGridView; -// const GridViewVTK gridView_VTK = grid_VTK.leafGridView(); - -// FTKfillerContainer<dim> VTKFiller; -// VTKFiller.vtkPrestrainNorm(gridView_VTK, B_Term, "PrestrainBNorm"); - -// // WORKS Too -// VTKFiller.vtkProblemCell(gridView_VTK, B_Term, muLocal,"VTKProblemCell");; - - -// // TEST -// auto scalarP0FeBasis = makeBasis(gridView_VTK,lagrange<0>()); -// auto scalarP1FeBasis = makeBasis(gridView_VTK,lagrange<1>()); - -// std::vector<double> B_CoeffP0; -// Functions::interpolate(scalarP0FeBasis, B_CoeffP0, B_Term); -// auto B_DGBF_P0 = Functions::makeDiscreteGlobalBasisFunction<double>(scalarP0FeBasis, B_CoeffP0); - - - -// VTKWriter<GridView> PrestrainVtkWriter(gridView_VTK); - -// PrestrainVtkWriter.addCellData( -// B_DGBF_P0, -// VTK::FieldInfo("B_P0", VTK::FieldInfo::Type::scalar, 1)); - -// PrestrainVtkWriter.write(outputPath + "/PrestrainFunctions-level"+ std::to_string(level) ); -// std::cout << "wrote data to file:" + outputPath +"/PrestrainFunctions-level" + std::to_string(level) << std::endl; - -// } - - - - - levelCounter++; - } // Level-Loop End - - - - - ////////////////////////////////////////// - //--- Print Storage - int tableWidth = 12; - std::cout << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("q12",tableWidth) << " | " - << center("q23",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - std::cout << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << center("Levels ",tableWidth) << " | " - << center("q1",tableWidth) << " | " - << center("q2",tableWidth) << " | " - << center("q3",tableWidth) << " | " - << center("q12",tableWidth) << " | " - << center("q23",tableWidth) << " | " - << center("b1",tableWidth) << " | " - << center("b2",tableWidth) << " | " - << center("b3",tableWidth) << " | " << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - - int StorageCount2 = 0; - for(auto& v: Storage_Quantities) - { - std::visit([tableWidth](auto&& arg){std::cout << center(prd(arg,5,1),tableWidth) << " | ";}, v); - std::visit([tableWidth, &log](auto&& arg){log << center(prd(arg,5,1),tableWidth) << " & ";}, v); - StorageCount2++; - if(StorageCount2 % 9 == 0 ) - { - std::cout << std::endl; - log << std::endl; - } - } - std::cout << std::string(tableWidth*9 + 3*9, '-') << "\n"; - log << std::string(tableWidth*9 + 3*9, '-') << "\n"; - - log.close(); - - std::cout << "Total time elapsed: " << globalTimer.elapsed() << std::endl; - - */ - - -} diff --git a/src/deprecated_code/elasticityTensor-globalFunctionVersion/CorrectorComputer.hh b/src/deprecated_code/elasticityTensor-globalFunctionVersion/CorrectorComputer.hh deleted file mode 100644 index 633b2e7f4c8bccf7c183c4b95da47715cac6f494..0000000000000000000000000000000000000000 --- a/src/deprecated_code/elasticityTensor-globalFunctionVersion/CorrectorComputer.hh +++ /dev/null @@ -1,1325 +0,0 @@ -#ifndef DUNE_MICROSTRUCTURE_CORRECTORCOMPUTER_HH -#define DUNE_MICROSTRUCTURE_CORRECTORCOMPUTER_HH - -#include <dune/common/parametertree.hh> -#include <dune/common/float_cmp.hh> -#include <dune/istl/matrixindexset.hh> -#include <dune/functions/functionspacebases/interpolate.hh> -#include <dune/functions/gridfunctions/gridviewfunction.hh> -#include <dune/functions/gridfunctions/discreteglobalbasisfunction.hh> -#include <dune/microstructure/matrix_operations.hh> - -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number -#include <dune/solvers/solvers/umfpacksolver.hh> - -using namespace Dune; -// using namespace Functions; -using namespace MatrixOperations; - -using std::shared_ptr; -using std::make_shared; -using std::fstream; - - -template <class Basis, class Material> //, class LocalScalar, class Local2Tensor> // LocalFunction derived from basis? -class CorrectorComputer { - -public: - static const int dimworld = 3; //GridView::dimensionworld; - static const int dim = Basis::GridView::dimension; //const int dim = Domain::dimension; - - using GridView = typename Basis::GridView; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - - using ScalarRT = FieldVector< double, 1>; - using VectorRT = FieldVector< double, dimworld>; - using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - using FuncScalar = std::function< ScalarRT(const Domain&) >; - using FuncVector = std::function< VectorRT(const Domain&) >; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - - using VectorCT = BlockVector<FieldVector<double,1> >; - using MatrixCT = BCRSMatrix<FieldMatrix<double,1,1> >; - using ElementMatrixCT = Matrix<FieldMatrix<double,1,1> >; - - using HierarchicVectorView = Dune::Functions::HierarchicVectorWrapper< VectorCT, double>; - -protected: -//private: - const Basis& basis_; - - - const Material& material_; - - fstream& log_; // Output-log - const ParameterTree& parameterSet_; - - const FuncScalar mu_; - const FuncScalar lambda_; - double gamma_; - - MatrixCT stiffnessMatrix_; - VectorCT load_alpha1_,load_alpha2_,load_alpha3_; //right-hand side(load) vectors - - VectorCT x_1_, x_2_, x_3_; // (all) Corrector coefficient vectors - VectorCT phi_1_, phi_2_, phi_3_; // Corrector phi_i coefficient vectors - FieldVector<double,3> m_1_, m_2_, m_3_; // Corrector m_i coefficient vectors - - MatrixRT M1_, M2_, M3_; // (assembled) corrector matrices M_i - const std::array<MatrixRT*, 3 > mContainer = {&M1_ , &M2_, &M3_}; - const std::array<VectorCT, 3> phiContainer = {phi_1_,phi_2_,phi_3_}; - - // ---- Basis for R_sym^{2x2} - MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - MatrixRT G2_ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0, 0.0, 0.0}}; - MatrixRT G3_ {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > MatrixBasisContainer_ = {G1_, G2_, G3_}; - - Func2Tensor x3G_1_ = [] (const Domain& x) { - return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - }; - - Func2Tensor x3G_2_ = [] (const Domain& x) { - return MatrixRT{{0.0, 0.0, 0.0}, {0.0, 1.0*x[2], 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_3_ = [] (const Domain& x) { - return MatrixRT{{0.0, (1.0/sqrt(2.0))*x[2], 0.0}, {(1.0/sqrt(2.0))*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - const std::array<Func2Tensor, 3> x3MatrixBasisContainer_ = {x3G_1_, x3G_2_, x3G_3_}; - - // --- Offset between basis indices - const int phiOffset_; - -public: - /////////////////////////////// - // constructor - /////////////////////////////// - CorrectorComputer( const Basis& basis, - const Material& material, - const FuncScalar& mu, - const FuncScalar& lambda, - double gamma, - std::fstream& log, - const ParameterTree& parameterSet) - : basis_(basis), - material_(material), - mu_(mu), - lambda_(lambda), - gamma_(gamma), - log_(log), - parameterSet_(parameterSet), - phiOffset_(basis.size()) - { - - assemble(); - - // if (parameterSet.get<bool>("stiffnessmatrix_cellproblem_to_csv")) - // csvSystemMatrix(); - // if (parameterSet.get<bool>("rhs_cellproblem_to_csv")) - // csvRHSs(); - // if (parameterSet.get<bool>("rhs_cellproblem_to_vtk")) - // vtkLoads(); - } - - - // ----------------------------------------------------------------- - // --- Assemble Corrector problems - void assemble() - { - Dune::Timer StiffnessTimer; - assembleCellStiffness(stiffnessMatrix_); - std::cout << "Stiffness assembly Timer: " << StiffnessTimer.elapsed() << std::endl; - - assembleCellLoad(load_alpha1_ ,x3G_1_); - assembleCellLoad(load_alpha2_ ,x3G_2_); - assembleCellLoad(load_alpha3_ ,x3G_3_); - }; - - - - /////////////////////////////// - // getter - /////////////////////////////// - const shared_ptr<Basis> getBasis() {return make_shared<Basis>(basis_);} - - ParameterTree getParameterSet() const {return parameterSet_;} - - fstream* getLog(){return &log_;} - - double getGamma(){return gamma_;} - - shared_ptr<MatrixCT> getStiffnessMatrix(){return make_shared<MatrixCT>(stiffnessMatrix_);} - shared_ptr<VectorCT> getLoad_alpha1(){return make_shared<VectorCT>(load_alpha1_);} - shared_ptr<VectorCT> getLoad_alpha2(){return make_shared<VectorCT>(load_alpha2_);} - shared_ptr<VectorCT> getLoad_alpha3(){return make_shared<VectorCT>(load_alpha3_);} - - shared_ptr<FuncScalar> getMu(){return make_shared<FuncScalar>(mu_);} - shared_ptr<FuncScalar> getLambda(){return make_shared<FuncScalar>(lambda_);} - - - // --- Get Correctors - // shared_ptr<VectorCT> getMcontainer(){return make_shared<VectorCT>(mContainer);} - // auto getMcontainer(){return make_shared<std::array<MatrixRT*, 3 > >(mContainer);} - auto getMcontainer(){return mContainer;} - shared_ptr<std::array<VectorCT, 3>> getPhicontainer(){return make_shared<std::array<VectorCT, 3>>(phiContainer);} - - - // shared_ptr<std::array<VectorRT, 3>> getBasiscontainer(){return make_shared<std::array<VectorRT, 3>>(basisContainer_);} - auto getMatrixBasiscontainer(){return make_shared<std::array<MatrixRT,3 >>(MatrixBasisContainer_);} - // auto getx3MatrixBasiscontainer(){return make_shared<std::array<Func2Tensor, 3>>(x3MatrixBasisContainer_);} - auto getx3MatrixBasiscontainer(){return x3MatrixBasisContainer_;} - - - - - - // shared_ptr<VectorCT> getCorr_a(){return make_shared<VectorCT>(x_a_);} - shared_ptr<VectorCT> getCorr_phi1(){return make_shared<VectorCT>(phi_1_);} - shared_ptr<VectorCT> getCorr_phi2(){return make_shared<VectorCT>(phi_2_);} - shared_ptr<VectorCT> getCorr_phi3(){return make_shared<VectorCT>(phi_3_);} - - - // Get the occupation pattern of the stiffness matrix - void getOccupationPattern(MatrixIndexSet& nb) - { - // OccupationPattern: - // | phi*phi m*phi | - // | phi *m m*m | - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - nb.resize(basis_.size()+3, basis_.size()+3); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - for (size_t i=0; i<localView.size(); i++) - { - // The global index of the i-th vertex of the element - auto row = localView.index(i); - for (size_t j=0; j<localView.size(); j++ ) - { - // The global index of the j-th vertex of the element - auto col = localView.index(j); - nb.add(row[0],col[0]); // nun würde auch nb.add(row,col) gehen.. - } - } - for (size_t i=0; i<localView.size(); i++) - { - auto row = localView.index(i); - - for (size_t j=0; j<3; j++ ) - { - nb.add(row,phiOffset+j); // m*phi part of StiffnessMatrix - nb.add(phiOffset+j,row); // phi*m part of StiffnessMatrix - } - } - for (size_t i=0; i<3; i++ ) - for (size_t j=0; j<3; j++ ) - { - nb.add(phiOffset+i,phiOffset+j); // m*m part of StiffnessMatrix - } - } - ////////////////////////////////////////////////////////////////// - // setOneBaseFunctionToZero - ////////////////////////////////////////////////////////////////// - if(parameterSet_.get<bool>("set_oneBasisFunction_Zero ", true)){ - FieldVector<int,3> row; - unsigned int arbitraryLeafIndex = parameterSet_.get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet_.get<unsigned int>("arbitraryElementNumber", 0); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); // macht keinen Unterschied ob hier k oder 0.. - const auto nSf = localFiniteElement.localBasis().size(); - assert(arbitraryLeafIndex < nSf ); - assert(arbitraryElementNumber < basis_.gridView().size(0)); // "arbitraryElementNumber larger than total Number of Elements" - - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - row = arbitraryComponentwiseIndices(arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<3; k++) - nb.add(row[k],row[k]); - } - std::cout << "finished occupation pattern\n"; - } - - - template<class localFunction1, class localFunction2> - void computeElementStiffnessMatrix(const typename Basis::LocalView& localView, - ElementMatrixCT& elementMatrix, - const localFunction1& mu, - const localFunction2& lambda - ) - { - // Local StiffnessMatrix of the form: - // | phi*phi m*phi | - // | phi *m m*m | - auto element = localView.element(); - auto geometry = element.geometry(); - // using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - elementMatrix.setSize(localView.size()+3, localView.size()+3); //extend by dim ´R_sym^{2x2} - elementMatrix = 0; - - - auto elasticityTensor = material_.getElasticityTensor(); - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - // std::cout << "localView.size(): " << localView.size() << std::endl; - // std::cout << "nSf : " << nSf << std::endl; - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} // wird nicht als Funktion benötigt da konstant... - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - // double elementContribution = 0.0; - - // std::cout << "Print QuadratureOrder:" << orderQR << std::endl; //TEST` - - int QPcounter= 0; - for (const auto& quadPoint : quad) - { - QPcounter++; - const auto& quadPos = quadPoint.position(); - const auto jacobianInverseTransposed = geometry.jacobianInverseTransposed(quadPos); - const auto integrationElement = geometry.integrationElement(quadPos); - - std::vector< FieldMatrix< double, 1, dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, - referenceGradients); - // Compute the shape function gradients on the grid element - std::vector<FieldVector<double,dim> > gradients(referenceGradients.size()); - - for (size_t i=0; i<gradients.size(); i++) - jacobianInverseTransposed.mv(referenceGradients[i][0], gradients[i]); - - for (size_t l=0; l< dimworld; l++) - for (size_t j=0; j < nSf; j++ ) - { - size_t row = localView.tree().child(l).localIndex(j); - // (scaled) Deformation gradient of the test basis function - MatrixRT defGradientV(0); - defGradientV[l][0] = gradients[j][0]; // Y - defGradientV[l][1] = gradients[j][1]; //X2 - // defGradientV[l][2] = (1.0/gamma)*gradients[j][2]; //X3 - defGradientV[l][2] = gradients[j][2]; //X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma_),defGradientV); - // "phi*phi"-part - for (size_t k=0; k < dimworld; k++) - for (size_t i=0; i < nSf; i++) - { - // (scaled) Deformation gradient of the ansatz basis function - MatrixRT defGradientU(0); - defGradientU[k][0] = gradients[i][0]; // Y - defGradientU[k][1] = gradients[i][1]; //X2 - // defGradientU[k][2] = (1.0/gamma)*gradients[i][2]; //X3 - defGradientU[k][2] = gradients[i][2]; //X3 - // printmatrix(std::cout, defGradientU , "defGradientU", "--"); - defGradientU = crossSectionDirectionScaling((1.0/gamma_),defGradientU); - - - // auto etmp = material_.applyElasticityTensor(defGradientU,element.geometry().global(quadPos)); - auto etmp = elasticityTensor(defGradientU,element.geometry().global(quadPos)); - // printmatrix(std::cout, etmp, "etmp", "--"); - double energyDensity= scalarProduct(etmp,defGradientV); - - - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), defGradientU, defGradientV); //TEST - // double energyDensity = generalizedDensity(mu(quadPos), lambda(quadPos), defGradientU, defGradientV); // also works.. - - size_t col = localView.tree().child(k).localIndex(i); - - elementMatrix[row][col] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "m*phi" & "phi*m" - part - for( size_t m=0; m<3; m++) - { - // double energyDensityGphi= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),defGradientV); - double energyDensityGphi= scalarProduct(elasticityTensor(basisContainer[m],element.geometry().global(quadPos)),defGradientV); - // double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], defGradientV); - // double energyDensityGphi = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], defGradientV); //TEST - auto value = energyDensityGphi * quadPoint.weight() * integrationElement; - elementMatrix[row][localPhiOffset+m] += value; - elementMatrix[localPhiOffset+m][row] += value; - } - - } - // "m*m"-part - for(size_t m=0; m<3; m++) //TODO ist symmetric.. reicht die hälfte zu berechnen!!! - for(size_t n=0; n<3; n++) - { - - // std::cout << "QPcounter: " << QPcounter << std::endl; - // std::cout << "m= " << m << " n = " << n << std::endl; - // printmatrix(std::cout, basisContainer[m] , "basisContainer[m]", "--"); - // printmatrix(std::cout, basisContainer[n] , "basisContainer[n]", "--"); - // std::cout << "integrationElement:" << integrationElement << std::endl; - // std::cout << "quadPoint.weight(): "<< quadPoint.weight() << std::endl; - // std::cout << "mu(quadPos): " << mu(quadPos) << std::endl; - // std::cout << "lambda(quadPos): " << lambda(quadPos) << std::endl; - - double energyDensityGG= scalarProduct(elasticityTensor(basisContainer[m],element.geometry().global(quadPos)),basisContainer[n]); - // double energyDensityGG= scalarProduct(material_.applyElasticityTensor(basisContainer[m],element.geometry().global(quadPos)),basisContainer[n]); - - // double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), basisContainer[m], basisContainer[n]); - // double energyDensityGG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), basisContainer[m], basisContainer[n]); //TEST - elementMatrix[localPhiOffset+m][localPhiOffset+n] += energyDensityGG * quadPoint.weight() * integrationElement; // += !!!!! (Fixed-Bug) - - // std::cout << "energyDensityGG:" << energyDensityGG<< std::endl; - // std::cout << "product " << energyDensityGG * quadPoint.weight() * integrationElement << std::endl; - // printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); - } - } - // std::cout << "Number of QuadPoints:" << QPcounter << std::endl; - // printmatrix(std::cout, elementMatrix, "elementMatrix", "--"); - } - - - - // Compute the source term for a single element - // < L (sym[D_gamma*nabla phi_i] + M_i ), x_3G_alpha > - template<class LocalFunction1, class LocalFunction2, class Vector, class LocalForce> - void computeElementLoadVector( const typename Basis::LocalView& localView, - LocalFunction1& mu, - LocalFunction2& lambda, - Vector& elementRhs, - const LocalForce& forceTerm - ) - { - // | f*phi| - // | --- | - // | f*m | - // using Element = typename LocalView::Element; - const auto element = localView.element(); - const auto geometry = element.geometry(); - // constexpr int dim = Element::dimension; - // constexpr int dimworld = dim; - - // using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - - // Set of shape functions for a single element - const auto& localFiniteElement= localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - elementRhs.resize(localView.size() +3); - elementRhs = 0; - - // LocalBasis-Offset - const int localPhiOffset = localView.size(); - - /////////////////////////////////////////////// - // Basis for R_sym^{2x2} - ////////////////////////////////////////////// - MatrixRT G_1 {{1.0, 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.0}}; - MatrixRT G_3 {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > basisContainer = {G_1, G_2, G_3}; - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; // TEST - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - // std::cout << "Quad-Rule order used: " << orderQR << std::endl; - - for (const auto& quadPoint : quad) - { - const FieldVector<double,dim>& quadPos = quadPoint.position(); - const auto jacobian = geometry.jacobianInverseTransposed(quadPos); - const double integrationElement = geometry.integrationElement(quadPos); - - std::vector<FieldMatrix<double,1,dim> > referenceGradients; - localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceGradients); - - std::vector< FieldVector< double, dim> > gradients(referenceGradients.size()); - for (size_t i=0; i< gradients.size(); i++) - jacobian.mv(referenceGradients[i][0], gradients[i]); - - //TEST - // std::cout << "forceTerm(element.geometry().global(quadPos)):" << std::endl; - // std::cout << forceTerm(element.geometry().global(quadPos)) << std::endl; - // std::cout << "forceTerm(quadPos)" << std::endl; - // std::cout << forceTerm(quadPos) << std::endl; - // - // //TEST QUadrature - // std::cout << "quadPos:" << quadPos << std::endl; - // std::cout << "element.geometry().global(quadPos):" << element.geometry().global(quadPos) << std::endl; - // // // - // // // - // std::cout << "quadPoint.weight() :" << quadPoint.weight() << std::endl; - // std::cout << "integrationElement(quadPos):" << integrationElement << std::endl; - // std::cout << "mu(quadPos) :" << mu(quadPos) << std::endl; - // std::cout << "lambda(quadPos) :" << lambda(quadPos) << std::endl; - - - // "f*phi"-part - for (size_t i=0; i < nSf; i++) - for (size_t k=0; k < dimworld; k++) - { - // Deformation gradient of the ansatz basis function - MatrixRT defGradientV(0); - defGradientV[k][0] = gradients[i][0]; // Y - defGradientV[k][1] = gradients[i][1]; // X2 - // defGradientV[k][2] = (1.0/gamma_)*gradients[i][2]; // - defGradientV[k][2] = gradients[i][2]; // X3 - - defGradientV = crossSectionDirectionScaling((1.0/gamma_),defGradientV); - - double energyDensity= scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),defGradientV); - - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),(-1.0)*forceTerm(quadPos), defGradientV ); - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)),forceTerm(quadPos), defGradientV ); //TEST - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),(-1.0)*forceTerm(quadPos), defGradientV ); //TEST - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos),forceTerm(element.geometry().global(quadPos)), defGradientV ); //TEST - - size_t row = localView.tree().child(k).localIndex(i); - elementRhs[row] += energyDensity * quadPoint.weight() * integrationElement; - } - - // "f*m"-part - for (size_t m=0; m<3; m++) - { - double energyDensityfG = scalarProduct(material_.applyElasticityTensor((-1.0)*forceTerm(quadPos),element.geometry().global(quadPos)),basisContainer[m]); - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), (-1.0)*forceTerm(quadPos),basisContainer[m] ); - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(element.geometry().global(quadPos)), lambda(element.geometry().global(quadPos)), forceTerm(quadPos),basisContainer[m] ); //TEST - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), (-1.0)*forceTerm(quadPos),basisContainer[m] ); //TEST - // double energyDensityfG = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), forceTerm(element.geometry().global(quadPos)),basisContainer[m] );//TEST - elementRhs[localPhiOffset+m] += energyDensityfG * quadPoint.weight() * integrationElement; - // std::cout << "energyDensityfG * quadPoint.weight() * integrationElement: " << energyDensityfG * quadPoint.weight() * integrationElement << std::endl; - } - } - } - - - void assembleCellStiffness(MatrixCT& matrix) - { - std::cout << "assemble Stiffness-Matrix begins." << std::endl; - - MatrixIndexSet occupationPattern; - getOccupationPattern(occupationPattern); - occupationPattern.exportIdx(matrix); - matrix = 0; - - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambdaLocal = localFunction(lambdaGridF); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - const int localPhiOffset = localView.size(); - // Dune::Timer Time; - //std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - Matrix<FieldMatrix<double,1,1> > elementMatrix; - computeElementStiffnessMatrix(localView, elementMatrix, muLocal, lambdaLocal); - - // std::cout << "local assembly time:" << Time.elapsed() << std::endl; - - //printmatrix(std::cout, elementMatrix, "ElementMatrix", "--"); - //std::cout << "elementMatrix.N() : " << elementMatrix.N() << std::endl; - //std::cout << "elementMatrix.M() : " << elementMatrix.M() << std::endl; - - //TEST - //Check Element-Stiffness-Symmetry: - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - if(abs(elementMatrix[i][j] - elementMatrix[j][i]) > 1e-12 ) - std::cout << "ELEMENT-STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL STIFFNES ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t i=0; i<localPhiOffset; i++) - for (size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - matrix[row][col] += elementMatrix[i][j]; - } - for (size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - matrix[row][phiOffset+m] += elementMatrix[i][localPhiOffset+m]; - matrix[phiOffset+m][row] += elementMatrix[localPhiOffset+m][i]; - } - for (size_t m=0; m<3; m++ ) - for (size_t n=0; n<3; n++ ) - matrix[phiOffset+m][phiOffset+n] += elementMatrix[localPhiOffset+m][localPhiOffset+n]; - - // printmatrix(std::cout, matrix, "StiffnessMatrix", "--"); - } - } - - - void assembleCellLoad(VectorCT& b, - const Func2Tensor& forceTerm - ) - { - // std::cout << "assemble load vector." << std::endl; - b.resize(basis_.size()+3); - b = 0; - - auto localView = basis_.localView(); - const int phiOffset = basis_.dimension(); - - // Transform G_alpha's to GridViewFunctions/LocalFunctions - auto loadGVF = Dune::Functions::makeGridViewFunction(forceTerm, basis_.gridView()); - auto loadFunctional = localFunction(loadGVF); - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto muLocal = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambdaLocal = localFunction(lambdaGridF); - - - // int counter = 1; - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - muLocal.bind(element); - lambdaLocal.bind(element); - loadFunctional.bind(element); - - const int localPhiOffset = localView.size(); - // std::cout << "localPhiOffset : " << localPhiOffset << std::endl; - - VectorCT elementRhs; - // std::cout << "----------------------------------Element : " << counter << std::endl; //TEST - // counter++; - computeElementLoadVector(localView, muLocal, lambdaLocal, elementRhs, loadFunctional); - // computeElementLoadVector(localView, muLocal, lambdaLocal, gamma, elementRhs, forceTerm); //TEST - // printvector(std::cout, elementRhs, "elementRhs", "--"); - // printvector(std::cout, elementRhs, "elementRhs", "--"); - ////////////////////////////////////////////////////////////////////////////// - // GLOBAL LOAD ASSEMBLY - ////////////////////////////////////////////////////////////////////////////// - for (size_t p=0; p<localPhiOffset; p++) - { - auto row = localView.index(p); - b[row] += elementRhs[p]; - } - for (size_t m=0; m<3; m++ ) - b[phiOffset+m] += elementRhs[localPhiOffset+m]; - //printvector(std::cout, b, "b", "--"); - } - } - - // ----------------------------------------------------------------- - // --- Functions for global integral mean equals zero constraint - auto arbitraryComponentwiseIndices(const int elementNumber, - const int leafIdx - ) - { - // (Local Approach -- works for non Lagrangian-Basis too) - // Input : elementNumber & localIdx - // Output : determine all Component-Indices that correspond to that basis-function - auto localView = basis_.localView(); - - FieldVector<int,3> row; - int elementCounter = 0; - - for (const auto& element : elements(basis_.gridView())) - { - if(elementCounter == elementNumber) // get arbitraryIndex(global) for each Component ..alternativ:gridView.indexSet - { - localView.bind(element); - - for (int k = 0; k < 3; k++) - { - auto rowLocal = localView.tree().child(k).localIndex(leafIdx); //Input: LeafIndex! TODO bräuchte hier (Inverse ) Local-to-Leaf Idx Map - row[k] = localView.index(rowLocal); - // std::cout << "rowLocal:" << rowLocal << std::endl; - // std::cout << "row[k]:" << row[k] << std::endl; - } - } - elementCounter++; - } - return row; - } - - void setOneBaseFunctionToZero() - { - std::cout << "Setting one Basis-function to zero" << std::endl; - - // constexpr int dim = Basis::LocalView::Element::dimension; - - unsigned int arbitraryLeafIndex = parameterSet_.template get<unsigned int>("arbitraryLeafIndex", 0); - unsigned int arbitraryElementNumber = parameterSet_.template get<unsigned int>("arbitraryElementNumber", 0); - //Determine 3 global indices (one for each component of an arbitrary local FE-function) - FieldVector<int,3> row = arbitraryComponentwiseIndices(arbitraryElementNumber,arbitraryLeafIndex); - - for (int k = 0; k<dim; k++) - { - 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; - } - } - - - auto childToIndexMap(const int k) - { - // Input : child/component - // Output : determine all Indices that belong to that component - auto localView = basis_.localView(); - - std::vector<int> r = { }; - // for (int n: r) - // std::cout << n << ","<< std::endl; - - // Determine global indizes for each component k = 1,2,3.. in order to subtract correct (component of) integral Mean - // (global) Indices that correspond to component k = 1,2,3 - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - const auto& localFiniteElement = localView.tree().child(k).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - for(size_t j=0; j<nSf; j++) - { - auto Localidx = localView.tree().child(k).localIndex(j); // local indices - r.push_back(localView.index(Localidx)); // global indices - } - } - // Delete duplicate elements - // first remove consecutive (adjacent) duplicates - auto last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - // sort followed by unique, to remove all duplicates - std::sort(r.begin(), r.end()); - last = std::unique(r.begin(), r.end()); - r.erase(last, r.end()); - return r; - } - - - auto integralMean(VectorCT& coeffVector) - { - auto GVFunction = Functions::makeDiscreteGlobalBasisFunction<FieldVector<double,dim>>(basis_,coeffVector); - auto localfun = localFunction(GVFunction); - - auto localView = basis_.localView(); - - FieldVector<double,3> r = {0.0, 0.0, 0.0}; - double area = 0.0; - - // Compute Area integral & integral of FE-function - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1)+5; //TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - area += quadPoint.weight() * integrationElement; - - r += localfun(quadPos) * quadPoint.weight() * integrationElement; - } - } - // std::cout << "Domain-Area: " << area << std::endl; - return (1.0/area) * r ; - } - - - auto subtractIntegralMean(VectorCT& coeffVector) - { - // Substract correct Integral mean from each associated component function - auto IM = integralMean(coeffVector); - - for(size_t k=0; k<dim; k++) - { - //std::cout << "Integral-Mean: " << IM[k] << std::endl; - auto idx = childToIndexMap(k); - for ( int i : idx) - coeffVector[i] -= IM[k]; - } - } - - - // ----------------------------------------------------------------- - // --- Solving the Corrector-problem: - auto solve() - { - std::cout << "start corrector solver..." << std::endl; - bool set_oneBasisFunction_Zero = parameterSet_.get<bool>("set_oneBasisFunction_Zero", false); - bool substract_integralMean = false; - if(parameterSet_.get<bool>("set_IntegralZero", false)) - { - set_oneBasisFunction_Zero = true; - substract_integralMean = true; - } - // set one basis-function to zero - if(set_oneBasisFunction_Zero) - setOneBaseFunctionToZero(); - - //TEST: Compute Condition Number (Can be very expensive !) - const bool verbose = true; - const unsigned int arppp_a_verbosity_level = 2; - const unsigned int pia_verbosity_level = 1; - MatrixInfo<MatrixCT> matrixInfo(stiffnessMatrix_,verbose,arppp_a_verbosity_level,pia_verbosity_level); - std::cout << "Get condition number of Stiffness_CE: " << matrixInfo.getCond2(true) << std::endl; - - /////////////////////////////////// - // --- Choose Solver --- - // 1 : CG-Solver - // 2 : GMRES - // 3 : QR (default) - // 4 : UMFPACK - /////////////////////////////////// - unsigned int Solvertype = parameterSet_.get<unsigned int>("Solvertype", 3); - unsigned int Solver_verbosity = parameterSet_.get<unsigned int>("Solver_verbosity", 2); - - // --- set initial values for solver - x_1_ = load_alpha1_; - x_2_ = load_alpha2_; - x_3_ = load_alpha3_; - - Dune::Timer SolverTimer; - if (Solvertype==1) // CG - SOLVER - { - std::cout << "------------ CG - Solver ------------" << std::endl; - MatrixAdapter<MatrixCT, VectorCT, VectorCT> op(stiffnessMatrix_); - - // Sequential incomplete LU decomposition as the preconditioner - SeqILU<MatrixCT, VectorCT, VectorCT> ilu0(stiffnessMatrix_,1.0); - int iter = parameterSet_.get<double>("iterations_CG", 999); - // Preconditioned conjugate-gradient solver - CGSolver<VectorCT> solver(op, - ilu0, //NULL, - 1e-8, // desired residual reduction factorlack - iter, // maximum number of iterations - Solver_verbosity, - true // Try to estimate condition_number - ); // verbosity of the solver - InverseOperatorResult statistics; - std::cout << "solve linear system for x_1.\n"; - solver.apply(x_1_, load_alpha1_, statistics); - std::cout << "solve linear system for x_2.\n"; - solver.apply(x_2_, load_alpha2_, statistics); - std::cout << "solve linear system for x_3.\n"; - solver.apply(x_3_, load_alpha3_, statistics); - log_ << "Solver-type used: " <<" CG-Solver" << std::endl; - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if (Solvertype==2) // GMRES - SOLVER - { - std::cout << "------------ GMRES - Solver ------------" << std::endl; - // Turn the matrix into a linear operator - MatrixAdapter<MatrixCT,VectorCT,VectorCT> stiffnessOperator(stiffnessMatrix_); - - // Fancy (but only) way to not have a preconditioner at all - Richardson<VectorCT,VectorCT> preconditioner(1.0); - - // Construct the iterative solver - RestartedGMResSolver<VectorCT> solver( - stiffnessOperator, // Operator to invert - preconditioner, // Preconditioner - 1e-10, // Desired residual reduction factor - 500, // Number of iterations between restarts, - // here: no restarting - 500, // Maximum number of iterations - Solver_verbosity); // Verbosity of the solver - - // Object storing some statistics about the solving process - InverseOperatorResult statistics; - - // solve for different Correctors (alpha = 1,2,3) - solver.apply(x_1_, load_alpha1_, statistics); //load_alpha1 now contains the corresponding residual!! - solver.apply(x_2_, load_alpha2_, statistics); - solver.apply(x_3_, load_alpha3_, statistics); - log_ << "Solver-type used: " <<" GMRES-Solver" << std::endl; - - std::cout << "statistics.converged " << statistics.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statistics.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statistics.iterations << std::endl; - } - //////////////////////////////////////////////////////////////////////////////////// - else if ( Solvertype==3)// QR - SOLVER - { - std::cout << "------------ QR - Solver ------------" << std::endl; - log_ << "solveLinearSystems: We use QR solver.\n"; - //TODO install suitesparse - SPQR<MatrixCT> sPQR(stiffnessMatrix_); - sPQR.setVerbosity(1); - InverseOperatorResult statisticsQR; - - sPQR.apply(x_1_, load_alpha1_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_2_, load_alpha2_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - sPQR.apply(x_3_, load_alpha3_, statisticsQR); - std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log_ << "Solver-type used: " <<" QR-Solver" << std::endl; - - } - //////////////////////////////////////////////////////////////////////////////////// - else if (Solvertype==4)// UMFPACK - SOLVER - { - std::cout << "------------ UMFPACK - Solver ------------" << std::endl; - log_ << "solveLinearSystems: We use UMFPACK solver.\n"; - - Dune::Solvers::UMFPackSolver<MatrixCT,VectorCT> solver; - solver.setProblem(stiffnessMatrix_,x_1_,load_alpha1_); - // solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_,x_2_,load_alpha2_); - // solver.preprocess(); - solver.solve(); - solver.setProblem(stiffnessMatrix_,x_3_,load_alpha3_); - // solver.preprocess(); - solver.solve(); - // sPQR.apply(x_1, load_alpha1, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - // sPQR.apply(x_2, load_alpha2, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - // sPQR.apply(x_3, load_alpha3, statisticsQR); - // std::cout << "statistics.converged " << statisticsQR.converged << std::endl; - // std::cout << "statistics.condition_estimate: " << statisticsQR.condition_estimate << std::endl; - // std::cout << "statistics.iterations: " << statisticsQR.iterations << std::endl; - log_ << "Solver-type used: " <<" UMFPACK-Solver" << std::endl; - } - std::cout << "Finished solving Corrector problems!" << std::endl; - std::cout << "Time for solving:" << SolverTimer.elapsed() << std::endl; - - //////////////////////////////////////////////////////////////////////////////////// - // Extract phi_alpha & M_alpha coefficients - //////////////////////////////////////////////////////////////////////////////////// - phi_1_.resize(basis_.size()); - phi_1_ = 0; - phi_2_.resize(basis_.size()); - phi_2_ = 0; - phi_3_.resize(basis_.size()); - phi_3_ = 0; - - for(size_t i=0; i<basis_.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]; - } - // assemble M_alpha's (actually iota(M_alpha) ) - - // MatrixRT M_1(0), M_2(0), M_3(0); - - M1_ = 0; - M2_ = 0; - M3_ = 0; - - for(size_t i=0; i<3; i++) - { - M1_ += m_1_[i]*MatrixBasisContainer_[i]; - M2_ += m_2_[i]*MatrixBasisContainer_[i]; - M3_ += m_3_[i]*MatrixBasisContainer_[i]; - } - - std::cout << "--- plot corrector-Matrices M_alpha --- " << std::endl; - printmatrix(std::cout, M1_, "Corrector-Matrix M_1", "--"); - printmatrix(std::cout, M2_, "Corrector-Matrix M_2", "--"); - printmatrix(std::cout, M3_, "Corrector-Matrix M_3", "--"); - log_ << "---------- OUTPUT ----------" << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_1: \n" << M1_ << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_2: \n" << M2_ << std::endl; - log_ << " --------------------" << std::endl; - log_ << "Corrector-Matrix M_3: \n" << M3_ << std::endl; - log_ << " --------------------" << std::endl; - - - if(parameterSet_.get<bool>("write_IntegralMean", false)) - { - std::cout << "check integralMean phi_1: " << std::endl; - auto A = integralMean(phi_1_); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean phi_1 : " << A[i] << std::endl; - } - } - if(substract_integralMean) - { - std::cout << " --- substracting integralMean --- " << std::endl; - subtractIntegralMean(phi_1_); - subtractIntegralMean(phi_2_); - subtractIntegralMean(phi_3_); - subtractIntegralMean(x_1_); - subtractIntegralMean(x_2_); - subtractIntegralMean(x_3_); - ////////////////////////////////////////// - // Check Integral-mean again: - ////////////////////////////////////////// - if(parameterSet_.get<bool>("write_IntegralMean", false)) - { - auto A = integralMean(phi_1_); - for(size_t i=0; i<3; i++) - { - std::cout << "Integral-Mean phi_1 (Check again) : " << A[i] << std::endl; - } - } - } - ///////////////////////////////////////////////////////// - // Write Solution (Corrector Coefficients) in Logs - ///////////////////////////////////////////////////////// - if(parameterSet_.get<bool>("write_corrector_phi1", false)) - { - log_ << "\nSolution of Corrector problems:\n"; - log_ << "\n Corrector_phi1:\n"; - log_ << x_1_ << std::endl; - } - if(parameterSet_.get<bool>("write_corrector_phi2", false)) - { - log_ << "-----------------------------------------------------"; - log_ << "\n Corrector_phi2:\n"; - log_ << x_2_ << std::endl; - } - if(parameterSet_.get<bool>("write_corrector_phi3", false)) - { - log_ << "-----------------------------------------------------"; - log_ << "\n Corrector_phi3:\n"; - log_ << x_3_ << std::endl; - } - - } - - - // ----------------------------------------------------------------- - // --- Write Correctos to VTK: - void writeCorrectorsVTK(const int level) - { - std::string vtkOutputName = parameterSet_.get("outputPath", "../../outputs") + "/CellProblem-result"; - std::cout << "vtkOutputName:" << vtkOutputName << std::endl; - - VTKWriter<typename Basis::GridView> vtkWriter(basis_.gridView()); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_1_), - VTK::FieldInfo("Corrector phi_1 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_2_), - VTK::FieldInfo("Corrector phi_2 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.addVertexData( - Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_, phi_3_), - VTK::FieldInfo("Corrector phi_3 level"+ std::to_string(level) , VTK::FieldInfo::Type::vector, dim)); - vtkWriter.write(vtkOutputName + "-level"+ std::to_string(level)); - std::cout << "wrote Corrector-VTK data to file: " + vtkOutputName + "-level" + std::to_string(level) << std::endl; - } - - // ----------------------------------------------------------------- - // --- Compute norms of the corrector functions: - void computeNorms() - { - computeL2Norm(); - computeL2SymGrad(); - - std::cout<< "Frobenius-Norm of M1_: " << M1_.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M2_: " << M2_.frobenius_norm() << std::endl; - std::cout<< "Frobenius-Norm of M3_: " << M3_.frobenius_norm() << std::endl; - } - - void computeL2Norm() - { - // IMPLEMENTATION with makeDiscreteGlobalBasisFunction - double error_1 = 0.0; - double error_2 = 0.0; - double error_3 = 0.0; - - auto localView = basis_.localView(); - auto GVFunc_1 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_); - auto GVFunc_2 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_); - auto GVFunc_3 = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - - for(const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun_1.bind(element); - localfun_2.bind(element); - localfun_3.bind(element); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(element.type(), orderQR); - - for(const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = element.geometry().integrationElement(quadPos); - error_1 += localfun_1(quadPos)*localfun_1(quadPos) * quadPoint.weight() * integrationElement; - error_2 += localfun_2(quadPos)*localfun_2(quadPos) * quadPoint.weight() * integrationElement; - error_3 += localfun_3(quadPos)*localfun_3(quadPos) * quadPoint.weight() * integrationElement; - } - } - std::cout << "L2-Norm(Corrector phi_1): " << sqrt(error_1) << std::endl; - std::cout << "L2-Norm(Corrector phi_2): " << sqrt(error_2) << std::endl; - std::cout << "L2-Norm(Corrector phi_3): " << sqrt(error_3) << std::endl; - - return; - } - - void computeL2SymGrad() - { - double error_1 = 0.0; - double error_2 = 0.0; - double error_3 = 0.0; - - auto localView = basis_.localView(); - - auto GVFunc_1 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_)); - auto GVFunc_2 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_)); - auto GVFunc_3 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_)); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - localfun_1.bind(element); - localfun_2.bind(element); - localfun_3.bind(element); - auto geometry = element.geometry(); - - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - const auto nSf = localFiniteElement.localBasis().size(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 ); - const auto& quad = QuadratureRules<double,dim>::rule(element.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const auto integrationElement = geometry.integrationElement(quadPos); - - auto scaledSymGrad1 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_1(quadPos))); - auto scaledSymGrad2 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_2(quadPos))); - auto scaledSymGrad3 = sym(crossSectionDirectionScaling(1.0/gamma_, localfun_3(quadPos))); - - error_1 += scalarProduct(scaledSymGrad1,scaledSymGrad1) * quadPoint.weight() * integrationElement; - error_2 += scalarProduct(scaledSymGrad2,scaledSymGrad2) * quadPoint.weight() * integrationElement; - error_3 += scalarProduct(scaledSymGrad3,scaledSymGrad3) * quadPoint.weight() * integrationElement; - } - } - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_1): " << sqrt(error_1) << std::endl; - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_2): " << sqrt(error_2) << std::endl; - std::cout << "L2-Norm(Symmetric scaled gradient of Corrector phi_3): " << sqrt(error_3) << std::endl; - return; - } - - - - // ----------------------------------------------------------------- - // --- Check Orthogonality relation Paper (75) - auto check_Orthogonality() - { - std::cout << "Check Orthogonality..." << std::endl; - - auto localView = basis_.localView(); - - auto GVFunc_1 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_1_)); - auto GVFunc_2 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_2_)); - auto GVFunc_3 = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis_,phi_3_)); - auto localfun_1 = localFunction(GVFunc_1); - auto localfun_2 = localFunction(GVFunc_2); - auto localfun_3 = localFunction(GVFunc_3); - const std::array<decltype(localfun_1)*,3> phiDerContainer = {&localfun_1 , &localfun_2 , &localfun_3 }; - - - auto muGridF = makeGridViewFunction(mu_, basis_.gridView()); - auto mu = localFunction(muGridF); - auto lambdaGridF = makeGridViewFunction(lambda_, basis_.gridView()); - auto lambda= localFunction(lambdaGridF); - - for(int a=0; a<3; a++) - for(int b=0; b<3; b++) - { - double energy = 0.0; - - auto DerPhi1 = *phiDerContainer[a]; - auto DerPhi2 = *phiDerContainer[b]; - - auto matrixFieldGGVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer_[a], basis_.gridView()); - auto matrixFieldG = localFunction(matrixFieldGGVF); - // auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - // auto matrixFieldB = localFunction(matrixFieldBGVF); - - // using GridView = typename Basis::GridView; - // using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - // using MatrixRT = FieldMatrix< double, dimWorld, dimWorld>; - - // std::cout << "Press key.." << std::endl; - // std::cin.get(); - - // TEST - // FieldVector<double,3> testvector = {1.0 , 1.0 , 1.0}; - // printmatrix(std::cout, matrixFieldFuncB(testvector) , "matrixFieldB(testvector) ", "--"); - - for (const auto& e : elements(basis_.gridView())) - { - localView.bind(e); - matrixFieldG.bind(e); - DerPhi1.bind(e); - DerPhi2.bind(e); - mu.bind(e); - lambda.bind(e); - - double elementEnergy = 0.0; - //double elementEnergy_HP = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - - auto Chi = sym(crossSectionDirectionScaling(1.0/gamma_, DerPhi2(quadPos))) + *mContainer[b]; - - auto strain1 = DerPhi1(quadPos); - - - strain1 = crossSectionDirectionScaling(1.0/gamma_, strain1); - strain1 = sym(strain1); - - - auto G = matrixFieldG(quadPos); - // auto G = matrixFieldG(e.geometry().global(quadPos)); //TEST - - auto tmp = G + *mContainer[a] + strain1; - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), tmp, Chi); - - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - // elementEnergy += strain1 * quadPoint.weight() * integrationElement; - //elementEnergy_HP += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - //higherPrecEnergy += elementEnergy_HP; - } - if(parameterSet_.get<bool>("print_debug", false)) - std::cout << "check_Orthogonality:" << "("<< a <<"," << b << "): " << energy << std::endl; - - if(energy > 1e-1) - std::cout << "WARNING: check Orthogonality! apparently (75) not satisfied on discrete level" << std::endl; - - } - return 0; - } - - - - // --- Check wheter stiffness matrix is symmetric - void checkSymmetry() - { - std::cout << " Check Symmetry of stiffness matrix..." << std::endl; - - auto localView = basis_.localView(); - - for (const auto& element : elements(basis_.gridView())) - { - localView.bind(element); - const int localPhiOffset = localView.size(); - - for(size_t i=0; i<localPhiOffset; i++) - for(size_t j=0; j<localPhiOffset; j++ ) - { - auto row = localView.index(i); - auto col = localView.index(j); - if(abs( stiffnessMatrix_[row][col] - stiffnessMatrix_[col][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - for(size_t i=0; i<localPhiOffset; i++) - for(size_t m=0; m<3; m++) - { - auto row = localView.index(i); - if(abs( stiffnessMatrix_[row][phiOffset_+m] - stiffnessMatrix_[phiOffset_+m][row]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - - } - for(size_t m=0; m<3; m++ ) - for(size_t n=0; n<3; n++ ) - { - if(abs(stiffnessMatrix_[phiOffset_+m][phiOffset_+n] - stiffnessMatrix_[phiOffset_+n][phiOffset_+m]) > 1e-12 ) - std::cout << "STIFFNESS MATRIX NOT SYMMETRIC!!!" << std::endl; - } - } - std::cout << "--- Symmetry test passed ---" << std::endl; - } - - - - - -}; // end class - -#endif \ No newline at end of file diff --git a/src/deprecated_code/elasticityTensor-globalFunctionVersion/EffectiveQuantitiesComputer.hh b/src/deprecated_code/elasticityTensor-globalFunctionVersion/EffectiveQuantitiesComputer.hh deleted file mode 100644 index 6c9d38ceec8ff5459ca879f9e37937a7d29595cb..0000000000000000000000000000000000000000 --- a/src/deprecated_code/elasticityTensor-globalFunctionVersion/EffectiveQuantitiesComputer.hh +++ /dev/null @@ -1,469 +0,0 @@ -#ifndef DUNE_MICROSTRUCTURE_EFFECTIVEQUANTITIESCOMPUTER_HH -#define DUNE_MICROSTRUCTURE_EFFECTIVEQUANTITIESCOMPUTER_HH - -#include <filesystem> - - -#include <dune/microstructure/matrix_operations.hh> -#include <dune/microstructure/CorrectorComputer.hh> - -#include <dune/istl/eigenvalue/test/matrixinfo.hh> // TEST: compute condition Number -#include <dune/istl/io.hh> -#include <dune/istl/matrix.hh> -#include <dune/common/parametertree.hh> - -using namespace Dune; -using namespace MatrixOperations; -using std::shared_ptr; -using std::make_shared; -using std::string; -using std::cout; -using std::endl; - -// template <class Basis> -// class EffectiveQuantitiesComputer : public CorrectorComputer<Basis,Material> { - -template <class Basis, class Material> -class EffectiveQuantitiesComputer { - -public: - static const int dimworld = 3; - // static const int nCells = 4; - - static const int dim = Basis::GridView::dimension; - - using Domain = typename CorrectorComputer<Basis,Material>::Domain; - - using VectorRT = typename CorrectorComputer<Basis,Material>::VectorRT; - using MatrixRT = typename CorrectorComputer<Basis,Material>::MatrixRT; - - using Func2Tensor = typename CorrectorComputer<Basis,Material>::Func2Tensor; - using FuncVector = typename CorrectorComputer<Basis,Material>::FuncVector; - - using VectorCT = typename CorrectorComputer<Basis,Material>::VectorCT; - - using HierarchicVectorView = typename CorrectorComputer<Basis,Material>::HierarchicVectorView; - -protected: - - CorrectorComputer<Basis,Material>& correctorComputer_; - Func2Tensor prestrain_; - const Material& material_; - -public: - VectorCT B_load_TorusCV_; //<B, Chi>_L2 - // FieldMatrix<double, dim, dim> Q_; //effective moduli <LF_i, F_j>_L2 - // FieldVector<double, dim> Bhat_; //effective loads induced by prestrain <LF_i, B>_L2 - // FieldVector<double, dim> Beff_; //effective strains Mb = ak - MatrixRT Q_; //effective moduli <LF_i, F_j>_L2 - VectorRT Bhat_; //effective loads induced by prestrain <LF_i, B>_L2 - VectorRT Beff_; //effective strains Mb = ak - - - // corrector parts - VectorCT phi_E_TorusCV_; //phi_i * (a,K)_i - VectorCT phi_perp_TorusCV_; - VectorCT phi_TorusCV_; - VectorCT phi_1_; //phi_i * (a,K)_i - VectorCT phi_2_; - VectorCT phi_3_; - - // is this really interesting??? - // double phi_E_L2norm_; - // double phi_E_H1seminorm_; - - // double phi_perp_L2norm_; - // double phi_perp_H1seminorm_; - - // double phi_L2norm_; - // double phi_H1seminorm_; - - // double Chi_E_L2norm_; - // double Chi_perp_L2norm_; - // double Chi_L2norm_; - - - double B_energy_; // < B, B >_L B = F + Chi_perp + B_perp - double F_energy_; // < F, F >_L - double Chi_perp_energy_; // < Chi_perp, Chi_perp >_L - double B_perp_energy_; // < B_perp, B_perp >_L - - //Chi(phi) is only implicit computed, can we store this? - - - /////////////////////////////// - // constructor - /////////////////////////////// - // EffectiveQuantitiesComputer(CorrectorComputer<Basis,Material>& correctorComputer, Func2Tensor prestrain) - // : correctorComputer_(correctorComputer), prestrain_(prestrain) - EffectiveQuantitiesComputer(CorrectorComputer<Basis,Material>& correctorComputer, - Func2Tensor prestrain, - const Material& material) - : correctorComputer_(correctorComputer), - prestrain_(prestrain), - material_(material) - { - - // computePrestressLoadCV(); - // computeEffectiveStrains(); - // Q_ = 0; - // Q_ = {{0.0,0.0,0.0},{0.0,0.0,0.0},{0.0,0.0,0.0}}; - // compute_phi_E_TorusCV(); - // compute_phi_perp_TorusCV(); - // compute_phi_TorusCV(); - - // computeCorrectorNorms(); - // computeChiNorms(); - // computeEnergiesPrestainParts(); - - // writeInLogfile(); - } - - - /////////////////////////////// - // getter - /////////////////////////////// - CorrectorComputer<Basis,Material> getCorrectorComputer(){return correctorComputer_;} - - const shared_ptr<Basis> getBasis() - { - return correctorComputer_.getBasis(); - } - - auto getQeff(){return Q_;} - auto getBeff(){return Beff_;} - - - // ----------------------------------------------------------------- - // --- Compute Effective Quantities - void computeEffectiveQuantities() - { - - // Get everything.. better TODO: with Inheritance? - // auto test = correctorComputer_.getLoad_alpha1(); - // auto phiContainer = correctorComputer_.getPhicontainer(); - auto MContainer = correctorComputer_.getMcontainer(); - auto MatrixBasisContainer = correctorComputer_.getMatrixBasiscontainer(); - auto x3MatrixBasisContainer = correctorComputer_.getx3MatrixBasiscontainer(); - auto mu_ = *correctorComputer_.getMu(); - auto lambda_ = *correctorComputer_.getLambda(); - auto gamma = correctorComputer_.getGamma(); - auto basis = *correctorComputer_.getBasis(); - ParameterTree parameterSet = correctorComputer_.getParameterSet(); - - shared_ptr<VectorCT> phiBasis[3] = {correctorComputer_.getCorr_phi1(), - correctorComputer_.getCorr_phi2(), - correctorComputer_.getCorr_phi3() - }; - - auto prestrainGVF = Dune::Functions::makeGridViewFunction(prestrain_, basis.gridView()); - auto prestrainFunctional = localFunction(prestrainGVF); - - Q_ = 0 ; - Bhat_ = 0; - - for(size_t a=0; a < 3; a++) - for(size_t b=0; b < 3; b++) - { - double energy = 0.0; - double prestrain = 0.0; - auto localView = basis.localView(); - // auto GVFunc_a = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,*phiContainer[a])); - auto GVFunc_a = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,*phiBasis[a])); - // auto GVFunc_b = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,phiContainer[b])); - auto localfun_a = localFunction(GVFunc_a); - // auto localfun_b = localFunction(GVFunc_b); - - /////////////////////////////////////////////////////////////////////////////// - - auto matrixFieldG1GVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer[a], basis.gridView()); - auto matrixFieldG1 = localFunction(matrixFieldG1GVF); - auto matrixFieldG2GVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer[b], basis.gridView()); - auto matrixFieldG2 = localFunction(matrixFieldG2GVF); - - auto muGridF = Dune::Functions::makeGridViewFunction(mu_, basis.gridView()); - auto mu = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambda_, basis.gridView()); - auto lambda= localFunction(lambdaGridF); - - // using GridView = typename Basis::GridView; - - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldG1.bind(e); - matrixFieldG2.bind(e); - localfun_a.bind(e); - // DerPhi2.bind(e); - mu.bind(e); - lambda.bind(e); - prestrainFunctional.bind(e); - - double elementEnergy = 0.0; - double elementPrestrain = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // int orderQR = 0; - // int orderQR = 1; - // int orderQR = 2; - // int orderQR = 3; - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - - auto Chi1 = sym(crossSectionDirectionScaling(1.0/gamma, localfun_a(quadPos))) + *MContainer[a]; - - - auto G1 = matrixFieldG1(quadPos); - auto G2 = matrixFieldG2(quadPos); - // auto G1 = matrixFieldG1(e.geometry().global(quadPos)); //TEST - // auto G2 = matrixFieldG2(e.geometry().global(quadPos)); //TEST - - auto X1 = G1 + Chi1; - // auto X2 = G2 + Chi2; - - - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), X1, G2); - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; // quad[quadPoint].weight() ??? - if (b==0) - { - elementPrestrain += linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), X1, prestrainFunctional(quadPos)) * quadPoint.weight() * integrationElement; - } - } - energy += elementEnergy; - prestrain += elementPrestrain; - - } - Q_[a][b] = energy; - if (b==0) - Bhat_[a] = prestrain; - } - if(parameterSet.get<bool>("print_debug", false)) - { - printmatrix(std::cout, Q_, "Matrix Q_", "--"); - printvector(std::cout, Bhat_, "Bhat_", "--"); - } - - /////////////////////////////// - // Compute effective Prestrain B_eff (by solving linear system) - ////////////////////////////// - - // std::cout << "------- Information about Q matrix -----" << std::endl; // TODO - // MatrixInfo<MatrixRT> matrixInfo(Q_,true,2,1); - // std::cout << "----------------------------------------" << std::endl; - Q_.solve(Beff_,Bhat_); - if(parameterSet.get<bool>("print_debug", false)) - printvector(std::cout, Beff_, "Beff_", "--"); - - - //LOG-Output - auto& log = *(correctorComputer_.getLog()); - log << "--- Prestrain Output --- " << std::endl; - log << "Bhat_: " << Bhat_ << std::endl; - log << "Beff_: " << Beff_ << " (Effective Prestrain)" << std::endl; - log << "------------------------ " << std::endl; - - // TEST - // std::cout << std::setprecision(std::numeric_limits<float_50>::digits10) << higherPrecEnergy << std::endl; - return ; - } - - - // ----------------------------------------------------------------- - // --- write Data to Matlab / Optimization-Code - void writeToMatlab(std::string outputPath) - { - std::cout << "write effective quantities to Matlab folder..." << std::endl; - //writeMatrixToMatlab(Q, "../../Matlab-Programs/QMatrix.txt"); - writeMatrixToMatlab(Q_, outputPath + "/QMatrix.txt"); - // write effective Prestrain in Matrix for Output - FieldMatrix<double,1,3> BeffMat; - BeffMat[0] = Beff_; - writeMatrixToMatlab(BeffMat, outputPath + "/BMatrix.txt"); - return; - } - - - - - template<class MatrixFunction> - double energySP(const MatrixFunction& matrixFieldFuncA, - const MatrixFunction& matrixFieldFuncB) - { - double energy = 0.0; - auto mu_ = *correctorComputer_.getMu(); - auto lambda_ = *correctorComputer_.getLambda(); - auto gamma = correctorComputer_.getGamma(); - auto basis = *correctorComputer_.getBasis(); - auto localView = basis.localView(); - - auto matrixFieldAGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncA, basis.gridView()); - auto matrixFieldA = localFunction(matrixFieldAGVF); - auto matrixFieldBGVF = Dune::Functions::makeGridViewFunction(matrixFieldFuncB, basis.gridView()); - auto matrixFieldB = localFunction(matrixFieldBGVF); - auto muGridF = Dune::Functions::makeGridViewFunction(mu_, basis.gridView()); - auto mu = localFunction(muGridF); - auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambda_, basis.gridView()); - auto lambda= localFunction(lambdaGridF); - for (const auto& e : elements(basis.gridView())) - { - localView.bind(e); - matrixFieldA.bind(e); - matrixFieldB.bind(e); - mu.bind(e); - lambda.bind(e); - - double elementEnergy = 0.0; - - auto geometry = e.geometry(); - const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - for (const auto& quadPoint : quad) - { - const auto& quadPos = quadPoint.position(); - const double integrationElement = geometry.integrationElement(quadPos); - double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), matrixFieldA(quadPos), matrixFieldB(quadPos)); - elementEnergy += energyDensity * quadPoint.weight() * integrationElement; - } - energy += elementEnergy; - } - return energy; - } - - - - // --- Alternative that does not use orthogonality relation (75) in the paper - // void computeFullQ() - // { - // auto MContainer = correctorComputer_.getMcontainer(); - // auto MatrixBasisContainer = correctorComputer_.getMatrixBasiscontainer(); - // auto x3MatrixBasisContainer = correctorComputer_.getx3MatrixBasiscontainer(); - // auto mu_ = *correctorComputer_.getMu(); - // auto lambda_ = *correctorComputer_.getLambda(); - // auto gamma = correctorComputer_.getGamma(); - // auto basis = *correctorComputer_.getBasis(); - - // shared_ptr<VectorCT> phiBasis[3] = {correctorComputer_.getCorr_phi1(), - // correctorComputer_.getCorr_phi2(), - // correctorComputer_.getCorr_phi3() - // }; - - // auto prestrainGVF = Dune::Functions::makeGridViewFunction(prestrain_, basis.gridView()); - // auto prestrainFunctional = localFunction(prestrainGVF); - - // Q_ = 0 ; - // Bhat_ = 0; - - // for(size_t a=0; a < 3; a++) - // for(size_t b=0; b < 3; b++) - // { - // double energy = 0.0; - // double prestrain = 0.0; - // auto localView = basis.localView(); - // // auto GVFunc_a = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,*phiContainer[a])); - // auto GVFunc_a = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,*phiBasis[a])); - // auto GVFunc_b = derivative(Functions::makeDiscreteGlobalBasisFunction<VectorRT>(basis,*phiBasis[b])); - // auto localfun_a = localFunction(GVFunc_a); - // auto localfun_b = localFunction(GVFunc_b); - - // /////////////////////////////////////////////////////////////////////////////// - // auto matrixFieldG1GVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer[a], basis.gridView()); - // auto matrixFieldG1 = localFunction(matrixFieldG1GVF); - // auto matrixFieldG2GVF = Dune::Functions::makeGridViewFunction(x3MatrixBasisContainer[b], basis.gridView()); - // auto matrixFieldG2 = localFunction(matrixFieldG2GVF); - - // auto muGridF = Dune::Functions::makeGridViewFunction(mu_, basis.gridView()); - // auto mu = localFunction(muGridF); - // auto lambdaGridF = Dune::Functions::makeGridViewFunction(lambda_, basis.gridView()); - // auto lambda= localFunction(lambdaGridF); - - // // using GridView = typename Basis::GridView; - - // for (const auto& e : elements(basis.gridView())) - // { - // localView.bind(e); - // matrixFieldG1.bind(e); - // matrixFieldG2.bind(e); - // localfun_a.bind(e); - // localfun_b.bind(e); - // mu.bind(e); - // lambda.bind(e); - // prestrainFunctional.bind(e); - - // double elementEnergy = 0.0; - // double elementPrestrain = 0.0; - - // auto geometry = e.geometry(); - // const auto& localFiniteElement = localView.tree().child(0).finiteElement(); - - // // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1 + 5 ); // TEST - // int orderQR = 2*(dim*localFiniteElement.localBasis().order()-1); - // // int orderQR = 0; - // // int orderQR = 1; - // // int orderQR = 2; - // // int orderQR = 3; - // const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), orderQR); - - // for (const auto& quadPoint : quad) - // { - // const auto& quadPos = quadPoint.position(); - // const double integrationElement = geometry.integrationElement(quadPos); - - // auto Chi1 = sym(crossSectionDirectionScaling(1.0/gamma, localfun_a(quadPos))) + *MContainer[a] + matrixFieldG1(quadPos); - // auto Chi2 = sym(crossSectionDirectionScaling(1.0/gamma, localfun_b(quadPos))) + *MContainer[b] + matrixFieldG2(quadPos); - - // // auto G1 = matrixFieldG1(quadPos); - // // auto G2 = matrixFieldG2(quadPos); - // // auto G1 = matrixFieldG1(e.geometry().global(quadPos)); //TEST - // // auto G2 = matrixFieldG2(e.geometry().global(quadPos)); //TEST - - // // auto X1 = G1 + Chi1; - // // auto X2 = G2 + Chi2; - - - // double energyDensity = linearizedStVenantKirchhoffDensity(mu(quadPos), lambda(quadPos), Chi1, Chi2); - // elementEnergy += energyDensity * quadPoint.weight() * integrationElement; // quad[quadPoint].weight() ??? - // } - // energy += elementEnergy; - // prestrain += elementPrestrain; - - // } - // Q_[a][b] = energy; - // if (b==0) - // Bhat_[a] = prestrain; - // } - // printmatrix(std::cout, Q_, "Matrix Q_", "--"); - // printvector(std::cout, Bhat_, "Bhat_", "--"); - // /////////////////////////////// - // // Compute effective Prestrain B_eff (by solving linear system) - // ////////////////////////////// - // // std::cout << "------- Information about Q matrix -----" << std::endl; // TODO - // // MatrixInfo<MatrixRT> matrixInfo(Q_,true,2,1); - // // std::cout << "----------------------------------------" << std::endl; - // Q_.solve(Beff_,Bhat_); - // printvector(std::cout, Beff_, "Beff_", "--"); - - // //LOG-Output - // auto& log = *(correctorComputer_.getLog()); - // log << "--- Prestrain Output --- " << std::endl; - // log << "Bhat_: " << Bhat_ << std::endl; - // log << "Beff_: " << Beff_ << " (Effective Prestrain)" << std::endl; - // log << "------------------------ " << std::endl; - // return ; - // } - - -}; // end class - - - -#endif \ No newline at end of file diff --git a/src/deprecated_code/elasticityTensor-globalFunctionVersion/material.py b/src/deprecated_code/elasticityTensor-globalFunctionVersion/material.py deleted file mode 100644 index 2487cfcefccab8a8dd652e88689cec09e82df5f9..0000000000000000000000000000000000000000 --- a/src/deprecated_code/elasticityTensor-globalFunctionVersion/material.py +++ /dev/null @@ -1,138 +0,0 @@ -import math -from python_matrix_operations import * - - - - -Phases = 3 - -mu_ = [3, 5, 0] -lambda_ = [9, 7, 0] - - - -#Indicator function that determines both phases -# x[0] : y1-component -# x[1] : y2-component -# x[2] : x3-component -# --- replace with your definition of indicatorFunction: -############### -# Wood -############### -def f(x): - theta=0.25 - # mu_ = [3, 5, 6] - # lambda_ = [9, 7, 8] - # mu_ = 3 5 6 - # lambda_ = 9 7 8 - - if ((abs(x[0]) < theta/2) and x[2]<0.25): - return [mu_[0], lambda_[0]] #latewood - # return 5 #latewood - elif ((abs(x[0]) > theta/2) and x[2]<0.25): - return [mu_[1], lambda_[1]] #latewood - # return 2 - else : - return [mu_[2],lambda_[2]] #latewood #Phase3 - # return 1 - - - -#Workaround -def muValue(x): - return mu_ - -def lambdaValue(x): - return lambda_ - - - - - -############### -# Cross -############### -# def f(x): -# theta=0.25 -# factor=1 -# if (x[0] <-1/2+theta and x[2]<-1/2+theta): -# return 1 #Phase1 -# elif (x[1]< -1/2+theta and x[2]>1/2-theta): -# return 2 #Phase2 -# else : -# return 0 #Phase3 - - - - - -# def f(x): -# # --- replace with your definition of indicatorFunction: -# if (abs(x[0]) > 0.25): -# return 1 #Phase1 -# else : -# return 0 #Phase2 - -def b1(x): - return [[1, 0, 0], [0,1,0], [0,0,1]] - -def b2(x): - return [[1, 0, 0], [0,1,0], [0,0,1]] - -def b3(x): - return [[0, 0, 0], [0,0,0], [0,0,0]] - -# mu=80 80 60 - -# lambda=80 80 25 - - -# --- elasticity tensor -# def L(G,x): -# def L(G): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] - - - - - - - - -# --- elasticity tensor -def L(G,x): - # input: symmetric matrix G, position x - # output: symmetric matrix LG - theta=0.25 - if (x[0] <-1/2+theta and x[2]<-1/2+theta): - return 2.0 * mu_[0] * sym(G) + lambda_[0] * trace(sym(G)) * Id() #Phase1 - elif (x[1]< -1/2+theta and x[2]>1/2-theta): - return 2.0 * mu_[1] * sym(G) + lambda_[1] * trace(sym(G)) * Id() #Phase2 - else : - return 2.0 * mu_[2] * sym(G) + lambda_[2] * trace(sym(G)) * Id() #Phase3 - # 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id(); - - - - - -# def H(G,x): -# # input: symmetric matrix G, position x -# # output: symmetric matrix LG -# if (abs(x[0]) > 0.25): -# return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] -# else: -# return [[0, 0, 0], [0,0,0], [0,0,0]] - - -def H(G,x): - # input: symmetric matrix G, position x - # output: symmetric matrix LG - if (abs(x[0]) > 0.25): - return [[1, 1, 1], [1, 1, 1],[1, 1, 1]] - else: - return [[0, 0, 0], [0,0,0], [0,0,0]] - -# 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id(); \ No newline at end of file diff --git a/src/deprecated_code/elasticityTensor-globalFunctionVersion/prestrainedMaterial.hh b/src/deprecated_code/elasticityTensor-globalFunctionVersion/prestrainedMaterial.hh deleted file mode 100644 index b0c68e3b24f545fd3ddb8deb66b882b7d07eb7e8..0000000000000000000000000000000000000000 --- a/src/deprecated_code/elasticityTensor-globalFunctionVersion/prestrainedMaterial.hh +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef DUNE_MICROSTRUCTURE_PRESTRAINEDMATERIAL_HH -#define DUNE_MICROSTRUCTURE_PRESTRAINEDMATERIAL_HH - - -#include <dune/grid/uggrid.hh> -#include <dune/grid/yaspgrid.hh> -#include <dune/microstructure/matrix_operations.hh> - -#include <dune/fufem/dunepython.hh> - - -using namespace Dune; -using namespace MatrixOperations; -using std::pow; -using std::abs; -using std::sqrt; -using std::sin; -using std::cos; - -using std::shared_ptr; -using std::make_shared; - - - -template <class GridView> // needed for GridViewFunctions -class prestrainedMaterial -{ - -public: - static const int dimworld = 3; //GridView::dimensionworld; - static const int dim = 3; //const int dim = Domain::dimension; - - - // using CellGridType = YaspGrid< dim, EquidistantOffsetCoordinates< double, dim>>; - // using Domain = typename CellGridType::LeafGridView::template Codim<0>::Geometry::GlobalCoordinate; - using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate; - using ScalarRT = FieldVector< double, 1>; - using VectorRT = FieldVector< double, dimworld>; - using MatrixRT = FieldMatrix< double, dimworld, dimworld>; - using FuncScalar = std::function< double(const Domain&) >; - using Func2Tensor = std::function< MatrixRT(const Domain&) >; - using Func2TensorParam = std::function< MatrixRT(const MatrixRT& ,const Domain&) >; - - -protected: - - const GridView& gridView_; - const ParameterTree& parameterSet_; - - - // const FieldVector<double , ...number of mu-Values/Phases> .. schwierig zur compile-time - - // const FuncScalar mu_; - // const FuncScalar lambda_; - // double gamma_; - - std::string materialFunctionName_; - - // --- Number of material phases? - // const int phases_; - - // Func2Tensor materialFunction_; //actually not needed?? - - // Func2Tensor elasticityTensor_; - Func2TensorParam elasticityTensor_; - -// VectorCT x_1_, x_2_, x_3_; // (all) Corrector coefficient vectors -// VectorCT phi_1_, phi_2_, phi_3_; // Corrector phi_i coefficient vectors -// FieldVector<double,3> m_1_, m_2_, m_3_; // Corrector m_i coefficient vectors - -// MatrixRT M1_, M2_, M3_; // (assembled) corrector matrices M_i -// const std::array<MatrixRT*, 3 > mContainer = {&M1_ , &M2_, &M3_}; -// const std::array<VectorCT, 3> phiContainer = {phi_1_,phi_2_,phi_3_}; - - // ---- Basis for R_sym^{2x2} - MatrixRT G1_ {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0, 0.0}}; - MatrixRT G2_ {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0, 0.0, 0.0}}; - MatrixRT G3_ {{0.0, 1.0/sqrt(2.0), 0.0}, {1.0/sqrt(2.0), 0.0, 0.0}, {0.0, 0.0, 0.0}}; - std::array<MatrixRT,3 > MatrixBasisContainer_ = {G1_, G2_, G3_}; - - Func2Tensor x3G_1_ = [] (const Domain& x) { - return MatrixRT{{1.0*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}}; //TODO könnte hier sign übergeben? - }; - - Func2Tensor x3G_2_ = [] (const Domain& x) { - return MatrixRT{{0.0, 0.0, 0.0}, {0.0, 1.0*x[2], 0.0}, {0.0, 0.0, 0.0}}; - }; - - Func2Tensor x3G_3_ = [] (const Domain& x) { - return MatrixRT{{0.0, (1.0/sqrt(2.0))*x[2], 0.0}, {(1.0/sqrt(2.0))*x[2], 0.0, 0.0}, {0.0, 0.0, 0.0}}; - }; - - const std::array<Func2Tensor, 3> x3MatrixBasisContainer_ = {x3G_1_, x3G_2_, x3G_3_}; - - -public: - /////////////////////////////// - // constructor - /////////////////////////////// - prestrainedMaterial(const GridView gridView, - const ParameterTree& parameterSet) // string: "name of material"? // mu_(mu), muValues? müsste Anzahl Phasen bereits kennen.. - : gridView_(gridView), - parameterSet_(parameterSet) - { - std::string materialFunctionName_ = parameterSet.get<std::string>("materialFunction", "material"); - Python::Module module = Python::import(materialFunctionName_); - - elasticityTensor_ = Python::make_function<MatrixRT>(module.get("L")); - - // Func2TensorParam elasticityTensor_ = Python::make_function<double>(module.get("L")); - // Func2Tensor materialFunction_ = Python::make_function<double>(module.get("f")); - // bool isotropic_ = true; // read from module File TODO - // Func2Tensor elasticityTensor_ = Python::make_function<double>(module.get("L")); - // Func2Tensor elasticityTensor_ = Python::make_function<MatrixRT>(module.get("L")); - } - - - - - MatrixRT applyElasticityTensor(const MatrixRT& G, const Domain& x) const - { - //--- apply elasticityTensor_ to input Matrix G at position x - return elasticityTensor_(G,x); - - } - - - - // ----------------------------------------------------------------- - // --- write material (grid)functions to VTK - void write_materialFunctions() - { - - - return; - - }; - - - - /////////////////////////////// - // getter - /////////////////////////////// - ParameterTree getParameterSet() const {return parameterSet_;} - - - // Func2Tensor getElasticityTensor() const {return elasticityTensor_;} - Func2TensorParam getElasticityTensor() const {return elasticityTensor_;} - - - // shared_ptr<Func2TensorParam> getElasticityTensor(){return make_shared<Func2TensorParam>(elasticityTensor_);} - - - //TODO getLameParameters() .. Throw Exception if isotropic_ = false! - - - - - // shared_ptr<MatrixCT> getStiffnessMatrix(){return make_shared<MatrixCT>(stiffnessMatrix_);} - // shared_ptr<VectorCT> getLoad_alpha1(){return make_shared<VectorCT>(load_alpha1_);} - // shared_ptr<VectorCT> getLoad_alpha2(){return make_shared<VectorCT>(load_alpha2_);} - // shared_ptr<VectorCT> getLoad_alpha3(){return make_shared<VectorCT>(load_alpha3_);} - - // shared_ptr<FuncScalar> getMu(){return make_shared<FuncScalar>(mu_);} - // shared_ptr<FuncScalar> getLambda(){return make_shared<FuncScalar>(lambda_);} - - - // --- Get Correctors - // shared_ptr<VectorCT> getMcontainer(){return make_shared<VectorCT>(mContainer);} - // auto getMcontainer(){return make_shared<std::array<MatrixRT*, 3 > >(mContainer);} - // auto getMcontainer(){return mContainer;} - // shared_ptr<std::array<VectorCT, 3>> getPhicontainer(){return make_shared<std::array<VectorCT, 3>>(phiContainer);} - - - // // shared_ptr<std::array<VectorRT, 3>> getBasiscontainer(){return make_shared<std::array<VectorRT, 3>>(basisContainer_);} - // auto getMatrixBasiscontainer(){return make_shared<std::array<MatrixRT,3 >>(MatrixBasisContainer_);} - // // auto getx3MatrixBasiscontainer(){return make_shared<std::array<Func2Tensor, 3>>(x3MatrixBasisContainer_);} - // auto getx3MatrixBasiscontainer(){return x3MatrixBasisContainer_;} - - - - - - // shared_ptr<VectorCT> getCorr_a(){return make_shared<VectorCT>(x_a_);} - // shared_ptr<VectorCT> getCorr_phi1(){return make_shared<VectorCT>(phi_1_);} - // shared_ptr<VectorCT> getCorr_phi2(){return make_shared<VectorCT>(phi_2_);} - // shared_ptr<VectorCT> getCorr_phi3(){return make_shared<VectorCT>(phi_3_);} - - - - - - -}; // end class - - - - -#endif