Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • Container-Setup
  • GeneralElasticityTensor
  • LoadVector_caching
  • assemble-into-multitypematrix
  • experiments
  • feature/bendingIsometries
  • localAssembly
  • local_minimizer
  • master
  • releases/2.9
  • storeGridandBasis
11 results

Target

Select target project
  • s7603593/dune-microstructure
  • s7603593/dune-microstructure-backup
2 results
Select Git revision
  • Container-Setup
  • ContainerBackup
  • GeneralElasticityTensor
  • LoadVector_caching
  • ParameterBackup
  • assemble-into-multitypematrix
  • commutingLimits
  • experiments
  • feature/newHermiteBasis
  • localAssembly
  • local_minimizer
  • master
  • oldHermiteBasis
  • releases/2.9
  • storeGridandBasis
  • updateFixDoFMethod
16 results
Show changes
Showing
with 1591 additions and 0 deletions
function [G, angle, Type, kappa] = symMinimization(print_Input,print_statPoint,print_Output,make_FunctionPlot, InputPath) %(Q_hom,B_eff)
syms v1 v2 q1 q2 q3 q12 b1 b2 b3
% -------- Options ----------
% % print_Input = false; %effective quantities
% print_Input = true;
% % print_statPoint = false;
% print_statPoint = true;
% print_Minimizer = true;
% % make_FunctionPlot = false;
% make_FunctionPlot = true;
print_Uniqueness = false;
check_StationaryPoints = false; % could be added to Input-Parameters..
compare_with_Classification = false; %maybe added later ---
%fprintf('Functions to be minimized:')
f_plus(v1,v2,q1,q2,q3,q12,b1,b2,b3) = q1*v1^4 + q2*v2^4+2*q3*v1^2*v2^2-2*(q1*b1*v1^2+ q2*b2*v2^2+sqrt(2)*q3*b3*v1*v2)...
+ q12*(v1^2*v2^2-b2*v1^2-b1*v2^2+b1*b2);
f_minus(v1,v2,q1,q2,q3,q12,b1,b2,b3) = q1*v1^4 + q2*v2^4+2*q3*v1^2*v2^2+2*(q1*b1*v1^2+ q2*b2*v2^2+sqrt(2)*q3*b3*v1*v2)...
+ q12*(v1^2*v2^2+b2*v1^2+b1*v2^2+b1*b2);
% ---- Fix parameters
if ~exist('InputPath','var')
% third parameter does not exist, so default it to something
absPath = "/home/klaus/Desktop/DUNE/dune-microstructure/outputs";
end
% 1. Import effective quantities from CellSolver-Code:
%read as sparse Matrix...
try %absolutePath
Qmat = spconvert(load(absPath + '' + "/QMatrix.txt"));
Bmat = spconvert(load(absPath + '' + "/BMatrix.txt"));
% fprintf('Use absolute Path')
catch ME % use relativePath
Qmat = spconvert(load('../outputs/QMatrix.txt'));
Bmat = spconvert(load('../outputs/BMatrix.txt'));
% fprintf('Use relative Path')
end
%convert to full matrix...
Qmat = full(Qmat);
Bmat = full(Bmat);
% --- TODO CHECK: assert if Q is orthotropic ???
if print_Input
fprintf('effective quadratic form:')
Qmat
fprintf('effective prestrain')
Bmat
% check if Q is (close to..) symmetric
% könnte Anti-symmetric part berechnen und schauen dass dieser klein?
% Test: issymmetric(Qmat) does not work for float matrices?
% symmetric part 0.5*(Qmat+Qmat')
% anti-symmetric part 0.5*(Qmat-Qmat')
if norm(0.5*(Qmat-Qmat'),'fro') < 1e-10
fprintf('Qmat (close to) symmetric \n')
else
fprintf('Qmat not symmetric \n')
end
% Check if B_eff is diagonal this is equivalent to b3 == 0
if abs(Bmat(3)) < 1e-10
fprintf('B_eff is diagonal (b3 == 0) \n')
else
fprintf('B_eff is NOT diagonal (b3 != 0) \n')
end
end
% CAST VALUES TO SYM FIRST? This is done anyway..
% % Substitute effective quantitites
f_plus = subs(f_plus,{q1, q2, q3, q12, b1, b2, b3}, {Qmat(1,1), Qmat(2,2), Qmat(3,3), Qmat(1,2), ...
Bmat(1), Bmat(2), Bmat(3)});
f_minus = subs(f_minus,{q1, q2, q3, q12, b1, b2, b3}, {Qmat(1,1), Qmat(2,2), Qmat(3,3), Qmat(1,2), ...
Bmat(1), Bmat(2), Bmat(3)});
% Compute the Gradients
df_plusx = diff(f_plus,v1);
df_plusy = diff(f_plus,v2);
df_minusx = diff(f_minus,v1);
df_minusy = diff(f_minus,v2);
% Setup Equations Grad(f) = 0
eq1 = df_plusx == 0;
eq2 = df_plusy == 0;
eqns_plus = [eq1, eq2];
eq3 = df_minusx == 0;
eq4 = df_minusy == 0;
eqns_minus = [eq3, eq4];
% ------- Symbolically Solve Equations:
% More robust (works even for values b_3 ~ 1e-08 ):
S_plus = solve(eqns_plus,v1,v2,'MaxDegree' , 5);
S_minus = solve(eqns_minus,v1,v2,'MaxDegree' , 5);
A_plus = S_plus.v1;
B_plus = S_plus.v2;
A_minus = S_minus.v1;
B_minus = S_minus.v2;
if check_StationaryPoints
%---------- TEST if Grad(f) = 0 ---------------------
fprintf('Testing equation grad(f) = 0 with stationary points')
for i = 1:size(A_plus,1)
fprintf('Testing %d.point (f_plus): ',i )
[ double(subs(subs(df_plusx,v1,A_plus(i)),v2,B_plus(i))), double(subs(subs(df_plusy,v1,A_plus(i)),v2,B_plus(i))) ]
end
for i = 1:size(A_minus,1)
fprintf('Testing %d.point (f_minus): ',i )
[double(subs(subs(df_minusx,v1,A_minus(i)),v2,B_minus(i))), double(subs(subs(df_minusy,v1,A_minus(i)),v2,B_minus(i)))]
end
% ------------------------------------
end
% --- Extract only Real-Solutions
% fprintf('real stationary points of f_plus:')
tmp1 = A_plus(imag(double(A_plus))==0 & imag(double(B_plus)) == 0);
tmp2 = B_plus(imag(double(A_plus))==0 & imag(double(B_plus)) == 0);
A_plus = tmp1;
B_plus = tmp2;
SP_plus = [A_plus,B_plus];
% fprintf('real stationary points of f_minus:')
tmp1 = A_minus(imag(double(A_minus))==0 & imag(double(B_minus)) == 0);
tmp2 = B_minus(imag(double(A_minus))==0 & imag(double(B_minus)) == 0);
A_minus = tmp1;
B_minus = tmp2;
SP_minus = [A_minus,B_minus];
% TODO one should use f_plus.subs(A_plus..) to compute function value symbolically?
% in the end only the stationaryPoints are used.. Ok to compare function values numerically
% Determine global Minimizer from stationary points:
% fprintf('function values at stationary points (f_plus):')
T_plus = arrayfun(@(v1,v2) double(f_plus(v1,v2,q1,q2,q3,q12,b1,b2,b3)),A_plus,B_plus,'UniformOutput', false);
T_plus = cell2mat(T_plus);
%Test: use Substitution
% subs(f_plus,{v1, v2}, {A_plus,B_plus})
% fprintf('function values at stationary points (f_minus):')
T_minus = arrayfun(@(v1,v2) double(f_minus(v1,v2,q1,q2,q3,q12,b1,b2,b3)),A_minus,B_minus,'UniformOutput', false);
T_minus = cell2mat(T_minus);
%Test: use Substitution
% T_minus = subs(f_minus,{v1, v2}, {A_minus,B_minus})
% double(T_minus)
if print_statPoint
fprintf('real stationary points of f_plus: ')
% SP_Plus %alternative: output as symbolic (can be unwieldy)
double(SP_plus)
fprintf('real stationary points of f_minus:')
% SP_Minus %alternative: output as symbolic (can be unwieldy)
double(SP_minus)
fprintf('function values at stationary points (f_plus):')
T_plus
fprintf('function values at stationary points (f_minus):')
T_minus
end
% --- Find Stationary Point(s) with minimum Value
[Min_plus,MinIdx_plus] = min(T_plus, [], 'all', 'linear'); %find one min...
[Min_minus,MinIdx_minus] = min(T_minus, [], 'all', 'linear');
% [Min_minus,MinIdx_minus] = min(T_minus) % works with symbolic too
% Compare Minimizers of f_plus & f_minus
[globalMinimizerValue,GlobalIdx] = min([Min_plus,Min_minus]);
if GlobalIdx == 1 %Min_plus % i.e. Global Minimizer is given by f_plus
GlobalMinimizer = SP_plus(MinIdx_plus,:);
sign = 1.0;
elseif GlobalIdx == 2 %Min_minus % i.e. Global Minimizer is given by f_minus
GlobalMinimizer = SP_minus(MinIdx_minus,:);
sign = -1.0;
end
% ------ Check if there are more SP with the same value...
MinIndices_minus = find(T_minus(:) == globalMinimizerValue); % Find indices of All Minima
MinIndices_plus = find(T_plus(:) == globalMinimizerValue); % Find indices of All Minima
numMinSP_minus = size(MinIndices_minus,1); % One of these is always >= 2 due to the structure of the roots..
numMinSP_plus = size(MinIndices_plus,1);
% AllMinSP_minus = SP_minus(MinIndices_minus,:)
% AllMinSP_minus = double(SP_minus(MinIndices_minus,:))
% AllMin = T_minus(MinIndices) %bereits klar dass diese selben funktionswert haben..
Minimizer = sign*(GlobalMinimizer'*GlobalMinimizer); % global minimizing Matrix G*
MinimizerCount = 1;
% different Stationary Points might correspond to the same minimizing
% Matrix G*... check this:
% Compare only with other StationaryPoints/Minimizers
% remove Index of Minimizer
if GlobalIdx == 1
MinIndices_plus = MinIndices_plus(MinIndices_plus~=MinIdx_plus);
elseif GlobalIdx == 2
MinIndices_minus = MinIndices_minus(MinIndices_minus~=MinIdx_minus);
end
MinIndices = cat(1,MinIndices_plus,MinIndices_minus); %[Minimizers-Indices f_plus, Minimizer-Indices f_minus]
for i = 1:(numMinSP_minus+numMinSP_plus-1) % -1: dont count Minimizer itself..
idx = MinIndices(i);
if i > numMinSP_plus
SP = SP_minus(idx,:);
else
SP = SP_plus(idx,:);
end
% SP_value = T_minus(idx) % not needed?
Matrix = sign*(SP'*SP);
if norm(double(Matrix-Minimizer),'fro') < eps %check is this sufficient here?
% both StationaryPoints correspond to the same
% (Matrix-)Minimizer
else
% StationaryPoint corresponds to a different (Matrix-)Minimizer
MinimizerCount = MinimizerCount + 1;
end
end
% ----------------------------------------------------------------------------------------------------------------
% Output Uniqueness of Minimizers:
if print_Uniqueness
if MinimizerCount == 1
fprintf('Unique Minimzier')
elseif MinimizerCount == 2
fprintf('Two Minimziers')
else
fprintf('1-Parameter family of Minimziers')
end
end
% --- determine the angle of the Minimizer
% a1 = Minimizer(1,1)
% a2 = Minimizer(2,2)
a1 = double(Minimizer(1,1));
a2 = double(Minimizer(2,2));
% compute the angle <(e,e_1) where Minimizer = kappa* (e (x) e)
e = [sqrt((a1/(a1+a2))), sqrt((a2/(a1+a2)))]; % always positive under sqrt here .. basically takes absolute value here
angle = atan2(e(2), e(1));
% compute curvature kappa
kappa = (a1 + a2);
% % CHeck off diagonal entries:
% sqrt(a1*a2);
% double(Minimizer);
G = double(Minimizer);
% --- "Classification" / Determine the TYPE of Minimizer by using
% the number of solutions (Uniqueness?)
% the angle (axial- or non-axial Minimizer)
% (Alternative compute det[GlobalMinimizer' e1'] where e1 = [1 0] ?)
% Check Uniqueness -- Options: unique/twoMinimizers/1-ParameterFamily
if MinimizerCount == 1
% fprintf('Unique Minimzier')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-9 || abs(angle) < 1e-9) % axial Minimizer
Type = 3;
else % non-axial Minimizer
Type = 1;
end
elseif MinimizerCount == 2
% fprintf('Two Minimziers')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-9 || abs(angle) < 1e-9) % axial Minimizer
Type = 3;
else % non-axial Minimizer
fprintf('ERROR: Two non-axial Minimizers cannot happen!')
end
else
% fprintf('1-Parameter family of Minimziers')
% Check if Minimizer is axial or non-axial:
if (abs(angle-pi/2) < 1e-9 || abs(angle) < 1e-9) % axial Minimizer
% fprintf('ERROR: axial Minimizers cannot happen for 1-Parameter Family!')
else % non-axial Minimizer
Type = 2;
end
end
% ------------------------------------------------------------------------------------------------------
if print_Output
fprintf(' --------- Output symMinimization --------')
fprintf('Global Minimizer v: (%d,%d) \n', GlobalMinimizer(1),GlobalMinimizer(2) )
fprintf('Global Minimizer Value f(v): %d \n', sym(globalMinimizerValue) ) %cast to symbolic
% fprintf('Global Minimizer Value : %d', globalMinimizerValue )
fprintf('Global Minimizer G: \n' )
G
fprintf("Angle = %d \n", angle)
fprintf("Curvature = %d \n", kappa)
fprintf("Type = %i \n", Type)
fprintf(' --------- -------------------- --------')
end
if make_FunctionPlot
fsurf(@(x,y) f_plus(x,y,q1,q2,q3,q12,b1,b2,b3)) % Plot functions
hold on
plot3(double(A_plus),double(B_plus),T_plus,'g*')
%Plot GlobalMinimizer:
hold on
plot3(double(GlobalMinimizer(1)),double(GlobalMinimizer(2)),globalMinimizerValue, 'o', 'Color','c')
% view(90,0)
% view(2)
figure
fsurf(@(x,y) f_minus(x,y,q1,q2,q3,q12,b1,b2,b3))
hold on
plot3(double(A_minus),double(B_minus),T_minus,'g*')
hold on
plot3(double(GlobalMinimizer(1)), double(GlobalMinimizer(2)),globalMinimizerValue, 'o', 'Color','c')
end
return
% Write symbolic solution to txt-File in Latex format
% fileID = fopen('txt.txt','w');
% fprintf(fileID,'%s' , latex(S_plus.v1));
% fclose(fileID);
Preparing the Sources
=========================
Additional to the software mentioned in README you'll need the
following programs installed on your system:
cmake >= 3.1
Getting started
---------------
If these preliminaries are met, you should run
dunecontrol all
which will find all installed dune modules as well as all dune modules
(not installed) which sources reside in a subdirectory of the current
directory. Note that if dune is not installed properly you will either
have to add the directory where the dunecontrol script resides (probably
./dune-common/bin) to your path or specify the relative path of the script.
Most probably you'll have to provide additional information to dunecontrol
(e. g. compilers, configure options) and/or make options.
The most convenient way is to use options files in this case. The files
define four variables:
CMAKE_FLAGS flags passed to cmake (during configure)
An example options file might look like this:
#use this options to configure and make if no other options are given
CMAKE_FLAGS=" \
-DCMAKE_CXX_COMPILER=g++-5 \
-DCMAKE_CXX_FLAGS='-Wall -pedantic' \
-DCMAKE_INSTALL_PREFIX=/install/path" #Force g++-5 and set compiler flags
If you save this information into example.opts you can pass the opts file to
dunecontrol via the --opts option, e. g.
dunecontrol --opts=example.opts all
More info
---------
See
dunecontrol --help
for further options.
The full build system is described in the dune-common/doc/buildsystem (Git version) or under share/doc/dune-common/buildsystem if you installed DUNE!
/* begin dune-microstructure
put the definitions for config.h specific to
your project here. Everything above will be
overwritten
*/
/* begin private */
/* Name of package */
#define PACKAGE "@DUNE_MOD_NAME@"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "@DUNE_MAINTAINER@"
/* Define to the full name of this package. */
#define PACKAGE_NAME "@DUNE_MOD_NAME@"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "@DUNE_MOD_NAME@ @DUNE_MOD_VERSION@"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "@DUNE_MOD_NAME@"
/* Define to the home page for this package. */
#define PACKAGE_URL "@DUNE_MOD_URL@"
/* Define to the version of this package. */
#define PACKAGE_VERSION "@DUNE_MOD_VERSION@"
/* end private */
/* Define to the version of dune-microstructure */
#define DUNE_MICROSTRUCTURE_VERSION "@DUNE_MICROSTRUCTURE_VERSION@"
/* Define to the major version of dune-microstructure */
#define DUNE_MICROSTRUCTURE_VERSION_MAJOR @DUNE_MICROSTRUCTURE_VERSION_MAJOR@
/* Define to the minor version of dune-microstructure */
#define DUNE_MICROSTRUCTURE_VERSION_MINOR @DUNE_MICROSTRUCTURE_VERSION_MINOR@
/* Define to the revision of dune-microstructure */
#define DUNE_MICROSTRUCTURE_VERSION_REVISION @DUNE_MICROSTRUCTURE_VERSION_REVISION@
/* end dune-microstructure
Everything below here will be overwritten
*/
add_subdirectory("doxygen")
# shortcut for creating the Doxyfile.in and Doxyfile
add_doxygen_target()
# This file contains local changes to the doxygen configuration
# please use '+=' to add files/directories to the lists
# The INPUT tag can be used to specify the files and/or directories that contain
# documented source files. You may enter file names like "myfile.cpp" or
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT += @top_srcdir@/dune/
# see e.g. dune-grid for the examples of mainpage and modules
# INPUT += @srcdir@/mainpage \
# @srcdir@/modules
# The EXCLUDE tag can be used to specify files and/or directories that should
# be excluded from the INPUT source files. This way you can easily exclude a
# subdirectory from a directory tree whose root is specified with the INPUT tag.
# EXCLUDE += @top_srcdir@/dune/microstructure/test
# The EXAMPLE_PATH tag can be used to specify one or more files or
# directories that contain example code fragments that are included (see
# the \include command).
# EXAMPLE_PATH += @top_srcdir@/src
# The IMAGE_PATH tag can be used to specify one or more files or
# directories that contain image that are included in the documentation (see
# the \image command).
# IMAGE_PATH += @top_srcdir@/dune/microstructure/pics
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
CXX=@CXX@
CC=@CC@
DEPENDENCIES=@REQUIRES@
Name: @PACKAGE_NAME@
Version: @VERSION@
Description: dune-microstructure module
URL: http://dune-project.org/
Requires: dune-common dune-istl dune-geometry dune-localfunctions dune-uggrid dune-grid dune-typetree dune-functions dune-solvers
Libs: -L${libdir}
Cflags: -I${includedir}
################################
# Dune module information file #
################################
# Name of the module
Module: dune-microstructure
Version: 1.0
Maintainer: klaus.boehnlein@tu-dresden.de
# Required build dependencies
Depends: dune-common dune-istl dune-geometry dune-localfunctions dune-uggrid dune-grid dune-typetree dune-functions
# Optional build dependencies
#Suggests:
add_subdirectory(microstructure)
#install headers
install(FILES microstructure.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/microstructure)
This diff is collapsed.
#ifndef DUNE_REDUCEDROD_CELLSOLVER_HH
#define DUNE_REDUCEDROD_CELLSOLVER_HH
#include <dune/reducedrod/cellassembler.hh>
#include <dune/functions/functionspacebases/hierarchicvectorwrapper.hh>
#include <dune/istl/operators.hh>
#include <dune/istl/preconditioners.hh>
#include <dune/istl/solvers.hh>
#include <dune/istl/spqr.hh>
template <class Basis>
class CellSolver {
public:
static const int nCompo = 3;
using VectorRT = typename CellAssembler<Basis>::VectorRT;
using VectorCT = typename CellAssembler<Basis>::VectorCT;
using MatrixCT = typename CellAssembler<Basis>::MatrixCT;
using HierarchicVectorView = Dune::Functions::HierarchicVectorWrapper<VectorCT, double>;
protected:
CellAssembler<Basis>& cellAssembler_;
MatrixCT stiffnessMatrix_;
VectorCT load_a_, load_K1_, load_K2_, load_K3_;
public:
// Constructor
CellSolver(CellAssembler<Basis>& cellAssembler)
: cellAssembler_(cellAssembler)
{
cellAssembler.assemble(stiffnessMatrix_,load_a_, load_K1_, load_K2_, load_K3_); //assemble hier rein?
}
//return ref ???
CellAssembler<Basis> getCellAssembler(){return cellAssembler_;}
MatrixCT * getStiffnessMatrix(){return &stiffnessMatrix_;}
VectorCT * getLoad_a(){return &load_a_;}
VectorCT * getLoad_K1(){return &load_K1_;}
VectorCT * getLoad_K2(){return &load_K2_;}
VectorCT * getLoad_K3(){return &load_K3_;}
void solveCorrectorSystems(VectorCT& x_a, VectorCT& x_K1, VectorCT& x_K2, VectorCT& x_K3)
{
std::cout << "CellSolver: Solve linear systems begin.\n";
ParameterTree parameterSet = cellAssembler_.getParameterSet();
//auto logPointer = cellAssembler_.getLog();
//auto & log = *logPointer;
auto & log = *(cellAssembler_.getLog());
int sizeBasisTorus_ = cellAssembler_.getSizeTorusElements();
x_a.resize(sizeBasisTorus_);
x_K1.resize(sizeBasisTorus_);
x_K2.resize(sizeBasisTorus_);
x_K3.resize(sizeBasisTorus_);
x_a = 0;
x_K1 = 0;
x_K2 = 0;
x_K3 = 0;
if (parameterSet.get<int>("iterate_with_load") == 1){
x_a = load_a_;
x_K1 = load_K1_;
x_K2 = load_K2_;
x_K3 = load_K3_;
}
if (parameterSet.get<int>("useCG") == 1){
std::cout << "We use CG solver.\n";
MatrixAdapter<MatrixCT, VectorCT, VectorCT> op(stiffnessMatrix_);
std::cout << "MatrixAdapter op.\n";
// 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 factor
iter, // maximum number of iterations
2); // verbosity of the solver
InverseOperatorResult statistics;
std::cout << "solve linear system for xa.\n";
solver.apply(x_a, load_a_, statistics);
std::cout << "solve linear system for xK1.\n";
solver.apply(x_K1, load_K1_, statistics);
std::cout << "solve linear system for xK2.\n";
solver.apply(x_K2, load_K2_, statistics);
std::cout << "solve linear system for xK3.\n";
solver.apply(x_K3, load_K3_, statistics);
}
if (parameterSet.get<int>("useQR") == 1){
std::cout << "We use QR solver.\n";
log << "solveLinearSystems: We use QR solver.\n";
//TODO install suitesparse
SPQR<MatrixCT> sPQR(stiffnessMatrix_);
sPQR.setVerbosity(1);
InverseOperatorResult statisticsQR;
sPQR.apply(x_a, load_a_, statisticsQR);
sPQR.apply(x_K1, load_K1_, statisticsQR);
sPQR.apply(x_K2, load_K2_, statisticsQR);
sPQR.apply(x_K3, load_K3_, statisticsQR);
}
// Write solutions in logs
if (parameterSet.get<int>("write_solutions_corrector_problems") == 1){
log << "\nSolution of Corrector problems:\n";
auto sizeComp = x_a.size()/nCompo;
std::vector<VectorRT> x_a_vec(sizeComp);
std::vector<VectorRT> x_K1_vec(sizeComp);
std::vector<VectorRT> x_K2_vec(sizeComp);
std::vector<VectorRT> x_K3_vec(sizeComp);
for (int i=0; i < x_a_vec.size(); i++){
x_a_vec[i] = VectorRT{x_a[i], x_a[i + sizeComp], x_a[i + 2*sizeComp]};
x_K1_vec[i] = VectorRT{x_K1[i], x_K1[i + sizeComp], x_K1[i + 2*sizeComp]};
x_K2_vec[i] = VectorRT{x_K2[i], x_K2[i + sizeComp], x_K2[i + 2*sizeComp]};
x_K3_vec[i] = VectorRT{x_K3[i], x_K3[i + sizeComp], x_K3[i + 2*sizeComp]};
}
log << "\nxa:\n";
for (int i=0; i < x_a_vec.size(); i++)
log << i << ": " << x_a_vec[i] << std::endl;
log << "\nxK1:\n";
for (int i=0; i < x_K1_vec.size(); i++)
log << i << ": " << x_K1_vec[i] << std::endl;
log << "\nxK2:\n";
for (int i=0; i < x_K2_vec.size(); i++)
log << i << ": " << x_K2_vec[i] << std::endl;
log << "\nxK3:\n";
for (int i=0; i < x_K3_vec.size(); i++)
log << i << ": " << x_K3_vec[i] << std::endl;
/*
log << "\nxa:\n";
for (int i=0; i < x_a.size(); i++)
log << i << " " << x_a[i] << std::endl;
log << "\nxK1:\n";
for (int i=0; i < x_K1.size(); i++)
log << i << " " << x_K1[i] << std::endl;
log << "\nxK2:\n";
for (int i=0; i < x_K2.size(); i++)
log << i << " " << x_K2[i] << std::endl;
log << "\nxK3:\n";
for (int i=0; i < x_K3.size(); i++)
log << i << " " << x_K3[i] << std::endl;
*/
}
}
void writeSystemMatrixAndRHSs()
{
ParameterTree parameterSet = cellAssembler_.getParameterSet();
auto logP = cellAssembler_.getLog();
auto & log = *logP;
if (parameterSet.get<int>("write_stiffness_matrix_Cell") == 1){
std::cout << "write stiffness matrix of cell problem in logfile\n";
log << "\nwriteSystemMatrixAndRHSs:\n";
printSparseMatrix(log, stiffnessMatrix_, "stiffnessMatrix with periodic bc", "");
//log << "\n";
//printmatrix(log, stiffnessMatrix_, "stiffnessMatrix with periodic bc", "");
//writeMatrixToMatlab(stiffnessMatrix, "../outputs/reducedrod_output/postprocessing/stiffness_matrix_for_octave.txt");
}
if (parameterSet.get<int>("write_loads_Cell") == 1){
std::cout << "write rhs of cell problem in logfile\n";
auto sizeComp = load_a_.size()/nCompo;
std::vector<VectorRT> load_a_vec(sizeComp);
std::vector<VectorRT> load_K1_vec(sizeComp);
std::vector<VectorRT> load_K2_vec(sizeComp);
std::vector<VectorRT> load_K3_vec(sizeComp);
for (int i=0; i < load_a_vec.size(); i++){
load_a_vec[i] = VectorRT{load_a_[i], load_a_[i + sizeComp], load_a_[i + 2*sizeComp]};
load_K1_vec[i] = VectorRT{load_K1_[i], load_K1_[i + sizeComp], load_K1_[i + 2*sizeComp]};
load_K2_vec[i] = VectorRT{load_K2_[i], load_K2_[i + sizeComp], load_K2_[i + 2*sizeComp]};
load_K3_vec[i] = VectorRT{load_K3_[i], load_K3_[i + sizeComp], load_K3_[i + 2*sizeComp]};
}
log << "\n RHS stretch strain - load_a:\n";
for (int i=0; i < load_a_vec.size(); i++)
log << i << " " << load_a_vec[i] << std::endl;
log << "\n RHS twist strain - load_K1:\n";
for (int i=0; i < load_K1_vec.size(); i++)
log << i << " " << load_K1_vec[i] << std::endl;
log << "\n RHS bend1 strain - load_K2:\n";
for (int i=0; i < load_K2_vec.size(); i++)
log << i << " " << load_K2_vec[i] << std::endl;
log << "\n RHS bend2 strain - load_K3:\n";
for (int i=0; i < load_K3_vec.size(); i++)
log << i << " " << load_K3_vec[i] << std::endl;
}
}
void plotLoads()
{
auto basis = cellAssembler_.getBasis();
auto perIndexMap = cellAssembler_.getIndexMapPeriodicBoundary();
auto size = basis->size();
VectorCT load_a_Ce(size);
VectorCT load_K1_Ce(size);
VectorCT load_K2_Ce(size);
VectorCT load_K3_Ce(size);
//index_PeriodicFE = indexmap(index_FE)
for (int i = 0; i < size; i++){
auto idx = perIndexMap[i];
load_a_Ce[i] = load_a_[idx];
load_K1_Ce[i] = load_K1_[idx];
load_K2_Ce[i] = load_K2_[idx];
load_K3_Ce[i] = load_K3_[idx];
}
std::cout << "plot loads.\n";
auto stretchF = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(load_a_Ce));
auto twistF = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(load_K1_Ce));
auto bend1F = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(load_K2_Ce));
auto bend2F = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(load_K3_Ce));
// Write result to VTK file, Maybe we write for every gamma?
VTKWriter<typename Basis::GridView> vtkWriter(basis->gridView());
vtkWriter.addVertexData(stretchF, VTK::FieldInfo("load_a_stretch", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(twistF, VTK::FieldInfo("load_K1_twist", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(bend1F, VTK::FieldInfo("load_K2_bend1", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(bend2F, VTK::FieldInfo("load_K3_bend2", VTK::FieldInfo::Type::vector, nCompo));
std::string outputPath = cellAssembler_.getParameterSet().get("outputPath", "../outputs/clampedprestressedrod_output");
vtkWriter.write(outputPath + "/loads_cell_problems");
}
}; // end class
#endif
#ifndef DUNE_REDUCEDROD_EFFECTIVEMODELCOMPUTER_HH
#define DUNE_REDUCEDROD_EFFECTIVEMODELCOMPUTER_HH
#include <dune/reducedrod/cellsolver.hh>
template <class Basis>
class EffectiveModelComputer {
public:
static const int nCompo = 3;
static const int nCells = 4;
using Domain = typename CellAssembler<Basis>::Domain;
using VectorRT = typename CellSolver<Basis>::VectorRT;
using MatrixRT = typename CellAssembler<Basis>::MatrixRT;
using Func2Tensor = typename CellAssembler<Basis>::Func2Tensor;
using VectorCT = typename CellSolver<Basis>::VectorCT;
using HierarchicVectorView = typename CellSolver<Basis>::HierarchicVectorView;
protected:
CellSolver<Basis>& cellSolver_;
Func2Tensor prestrain_;
VectorCT x_a_, x_K1_, x_K2_, x_K3_; // in torus basis
FieldMatrix<double, nCells, nCells> M_Ce_;
FieldVector<double, nCells> aeffKeff_;
public:
// Constructor
EffectiveModelComputer(CellSolver<Basis>& cellSolver, Func2Tensor prestrain)
: cellSolver_(cellSolver), prestrain_(prestrain)
{
cellSolver.solveCorrectorSystems(x_a_, x_K1_, x_K2_, x_K3_ );
computeEffectiveModel();
//computeCorrector();
}
VectorCT * getCorr_a(){return &x_a_;}
VectorCT * getCorr_K1(){return &x_K1_;}
VectorCT * getCorr_K2(){return &x_K2_;}
VectorCT * getCorr_K3(){return &x_K3_;}
FieldMatrix<double, nCells, nCells> getEffMaterial(){return M_Ce_;}
FieldVector<double, nCells> getEffPreStrain(){return aeffKeff_;}
CellSolver<Basis> getCellSolver(){return cellSolver_;}
const Basis* getCellBasis() {
auto cellAssembler = cellSolver_.getCellAssembler();
return cellAssembler.getBasis();}
void plotCorrectors()
{
std::cout << "Write corrector solutions.\n";
auto cellAssembler = cellSolver_.getCellAssembler();
auto basis = getCellBasis();
auto perIndexMap = cellAssembler.getIndexMapPeriodicBoundary();
auto size = basis->size();
VectorCT x_a_Ce(size);
VectorCT x_K1_Ce(size);
VectorCT x_K2_Ce(size);
VectorCT x_K3_Ce(size);
//index_PeriodicFE = indexmap(index_FE)
for (int i = 0; i < size; i++){
auto idx = perIndexMap[i];
x_a_Ce[i] = x_a_[idx];
x_K1_Ce[i] = x_K1_[idx];
x_K2_Ce[i] = x_K2_[idx];
x_K3_Ce[i] = x_K3_[idx];
}
VectorCT x_corrector(size);
computeCorrector(x_corrector);
auto stretchF = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(x_a_Ce));
auto twistF = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(x_K1_Ce));
auto bend1F = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(x_K2_Ce));
auto bend2F = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(x_K3_Ce));
auto correctorF = Functions::makeDiscreteGlobalBasisFunction<VectorRT>(Functions::subspaceBasis(*basis), HierarchicVectorView(x_corrector));
// Write result to VTK file, Maybe we write for every gamma?
VTKWriter<typename Basis::GridView> vtkWriter(basis->gridView());
vtkWriter.addVertexData(stretchF, VTK::FieldInfo("phi_a_stretch", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(twistF, VTK::FieldInfo("phi_K1_twist", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(bend1F, VTK::FieldInfo("phi_K2_bend1", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(bend2F, VTK::FieldInfo("phi_K3_bend2", VTK::FieldInfo::Type::vector, nCompo));
vtkWriter.addVertexData(correctorF, VTK::FieldInfo("phi_full", VTK::FieldInfo::Type::vector, nCompo));
std::string outputPath = cellAssembler.getParameterSet().get("outputPath", "../outputs/clampedprestressedrod_output");
vtkWriter.write(outputPath + "/corrector_solutions");
//add corrector
}
void computeCorrector(VectorCT& x_corrector)
{
VectorCT x_Corrector_Torus(x_a_);
x_Corrector_Torus *= aeffKeff_[0];
auto tmp_xK1 = x_K1_;
auto tmp_xK2 = x_K2_;
auto tmp_xK3 = x_K3_;
tmp_xK1 *= aeffKeff_[1];
tmp_xK2 *= aeffKeff_[2];
tmp_xK3 *= aeffKeff_[3];
x_Corrector_Torus += tmp_xK1;
x_Corrector_Torus += tmp_xK2;
x_Corrector_Torus += tmp_xK3;
auto cellAssembler = cellSolver_.getCellAssembler();
auto basis = cellAssembler.getBasis();
auto perIndexMap = cellAssembler.getIndexMapPeriodicBoundary();
x_corrector.resize(basis->size());
for (int i = 0; i < basis->size(); i++)
x_corrector[i] = x_Corrector_Torus[perIndexMap[i]];
}
private:
void computeEffectiveModel()
{
auto cellAssembler = cellSolver_.getCellAssembler();
ParameterTree parameterSet = cellAssembler.getParameterSet();
auto logP = cellAssembler.getLog();
auto & log = *logP;
// lateral stretch strain E_U1 = e1 ot e1
Func2Tensor E_a = [] (const Domain& z) //extra Klasse
{
return MatrixRT{{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
};
// twist in x2-x3 plane E_K1 = sym (e1 x (0,x2,x3)^T ot e1)
Func2Tensor E_K1 = [] (const Domain& z)
{
return MatrixRT{{0.0,-0.5*z[2], 0.5*z[1]}, {-0.5*z[2], 0.0 , 0.0 }, {0.5*z[1],0.0,0.0}};
};
// bend strain in x1-x2 plane E_K2 = sym (e2 x (0,x2,x3)^T ot e1)
Func2Tensor E_K2 = [] (const Domain& z)
{
return MatrixRT{{z[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0}};
};
// bend strain in x1-x3 plane E_K3 = sym (e3 x (0,x2,x3)^T ot e1)
Func2Tensor E_K3 = [] (const Domain& z)
{
return MatrixRT{{-z[1], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
};
VectorCT *xCorrectors[nCells] = {&x_a_, &x_K1_, &x_K2_, &x_K3_};
VectorCT *loadsCell[nCells] = {cellSolver_.getLoad_a(), cellSolver_.getLoad_K1(), cellSolver_.getLoad_K2(), cellSolver_.getLoad_K3()};
//using GridViewFunction_Ce = decltype(E_a);
const std::array<Func2Tensor*, nCells> strainsE = {&E_a, &E_K1, &E_K2, &E_K3};
//wir brauchen sym grad phi als gridFunction!
FieldMatrix<double, nCells, nCells> QEE(0);
// Assemble 4x4 matrix //symmetrisch? reicht hälfte zu füllen?
for (unsigned int k = 0; k < nCells; k++)
for (unsigned int l = 0; l < nCells; l++){
auto energyEkEl = cellAssembler.energy(*strainsE[k], *strainsE[l]); //<LE,E>
QEE[k][l] = energyEkEl;
M_Ce_[k][l]= 3.0*((*xCorrectors[k])*(*loadsCell[l])) + energyEkEl; //<LChi, Chi>= <E,Chi>, 2<LChi, E> // 3* ?
}// oder braucht man nicht periodische objekte?
/*
FieldMatrix<double, nCells, nCells> QChiChi(0);
FieldMatrix<double, nCells, nCells> QEChi(0);
if (parameterSet.get<bool>("material_computation_2"))
for (unsigned int k = 0; k < nCells; k++)
for (unsigned int l = 0; l < nCells; l++){
auto energyEE = cellAssembler.computeScalarTerm(*strainsE[k], *strainsE[l]); //<LE,E>
auto energyChiChi = cellAssembler.computeScalarTerm(*xCorrectors[k], *xCorrectors[l]);
auto energyEChi = cellAssembler.computeScalarTerm(*strainsE[k], *xCorrectors[l]);
QEE[k][l] = energyEE;
QChiChi[k][l] = energyChiChi;
QEChi[k][l] = energyEChi;
M_Ce_[k][l]= energyEE + energyChiChi + 2*energyEChi; //<LChi, Chi>= <E,Chi>, 2<LChi, E> // eher so ??
}
*/
VectorCT load_B;
cellAssembler.assembleLoadVector(prestrain_, load_B);
// Assemble rhs by projecting prestrain to strain basis
FieldVector<double, nCells> b;
for (unsigned int k = 0; k < nCells; k++){
auto strainsEkB = cellAssembler.energy(*strainsE[k], prestrain_); // <LB, E>
b[k]= (*xCorrectors[k]) * load_B + strainsEkB; // < B, chi>
}
M_Ce_.solve( aeffKeff_ ,b);
log << "\nQEE= \n";
for (int i = 0; i < nCells; i++)
log << QEE[i] << std::endl;
log << "\nM_Ce= \n";
for (int i = 0; i < nCells; i++)
log << M_Ce_[i] << std::endl;
log << "\nb= " << b << std::endl;
log << "\nstretch twist bend1 bend2\naeffKeff = "<< aeffKeff_ << std::endl;
std::cout << "\naeffKeff: stretch twist bend1 bend2 = "<< aeffKeff_ << std::endl;
}
}; // end class
#endif
#ifndef DUNE_MICROSTRUCTURE_MATRIXOPERATIONS_HH
#define DUNE_MICROSTRUCTURE_MATRIXOPERATIONS_HH
namespace MatrixOperations {
using namespace Dune;
using MatrixRT = FieldMatrix< double, 3, 3>;
using VectorRT = FieldVector< double, 3>;
using std::sin;
using std::cos;
static MatrixRT Id (){
MatrixRT Id(0);
for (int i=0;i<3;i++)
Id[i][i]=1.0;
return Id;
}
static double norm(VectorRT v){
return sqrt(pow(v[0],2) + pow(v[1],2) + pow(v[2],2));
}
static double norm(MatrixRT M){
return sqrt(
pow(M[0][0],2) + pow(M[0][1],2) + pow(M[0][2],2)
+ pow(M[1][0],2) + pow(M[1][1],2) + pow(M[1][2],2)
+ pow(M[2][0],2) + pow(M[2][1],2) + pow(M[2][2],2));
}
static MatrixRT sym (MatrixRT M) { // 1/2 (M^T + M)
MatrixRT ret(0);
for (int i = 0; i< 3; i++)
for (int j = 0; j< 3; j++)
ret[i][j] = 0.5 * (M[i][j] + M[j][i]);
return ret;
}
static VectorRT crossProduct (VectorRT v, VectorRT w) { // v otimes w
return {v[1]*w[2] - v[2]*w[1], -1*(v[0]*w[2] - v[2]*w[0]), v[0]*w[1] - v[1]*w[0]};
}
static MatrixRT rankoneTensorproduct (VectorRT v, VectorRT w) { // v otimes w
return
{{v[0]*w[0], v[1]*w[0], v[2]*w[0]},
{v[0]*w[1], v[1]*w[1], v[2]*w[1]},
{v[0]*w[2], v[1]*w[2], v[2]*w[2]}};
}
static MatrixRT nematicLiquidCrystal (double p, VectorRT n){ //B = 1/6*p*Id + 1/2*p*(n otimes n)
MatrixRT B(0);
for (int i=0;i<3;i++)
B[i][i]=p/6.0;
MatrixRT n_ot_n = rankoneTensorproduct(n,n);
n_ot_n*=p/2.0;
B += n_ot_n;
return B;
}
static MatrixRT biotStrainApprox (VectorRT U, VectorRT k, VectorRT e_cs){ //E_h = (U + k x e_cs, 0, 0)
VectorRT k_x_ecs = crossProduct(k, e_cs);
VectorRT U_plus_k_x_ecs = U + k_x_ecs;
VectorRT e_1 = {1, 0, 0};
return rankoneTensorproduct(U_plus_k_x_ecs, e_1);
}
static MatrixRT crossSectionDirectionScaling(double w, MatrixRT M){
return {M[0], w*M[1], w*M[2]};
}
static double trace (MatrixRT M){
return M[0][0]+ M[1][1] + M[2][2];
}
static double scalarProduct (MatrixRT M1, MatrixRT M2){
double sum = 0;
for (int i=0; i<3; i++)
for (int j=0; j<3; j++)
sum += M1[i][j] * M2[i][j];
return sum;
}
// static double linearizedStVenantKirchhoffDensity(double mu, double lambda, MatrixRT E1, MatrixRT E2){ // ?? Check with Robert
// E1= sym(E1);
// E2 = sym(E2);
// double t1 = scalarProduct(E1,E2);
// t1 *= 2* mu;
// double t2 = trace(E1)*trace(E2);
// t2 *= lambda;
// return t1 + t2;
// }
static double linearizedStVenantKirchhoffDensity(double mu, double lambda, MatrixRT E1, MatrixRT E2) // CHANGED
{
auto t1 = 2.0 * mu * sym(E1) + lambda * trace(sym(E1)) * Id();
return scalarProduct(t1,E2);
}
// --- Generalization: Define Quadratic QuadraticForm
static double QuadraticForm(const double mu, const double lambda, const MatrixRT M){
auto tmp1 = sym(M);
double tmp2 = norm(tmp1);
return lambda*std::pow(trace(M),2) + 2*mu*pow( tmp2 ,2);
// return lambda*std::pow(trace(M),2) + 2*mu*pow( norm( sym(M) ),2);
}
static double generalizedDensity(const double mu, const double lambda, MatrixRT F, MatrixRT G){
/// Write this whole File as a Class that uses lambda,mu as members ?
// Define L via Polarization-Identity from QuadratifForm
// <LF,G> := (1/2)*(Q(F+G) - Q(F) - Q(G) )
return (1.0/2.0)*(QuadraticForm(mu,lambda,F+G) - QuadraticForm(mu,lambda,F) - QuadraticForm(mu,lambda,G) );
}
static MatrixRT matrixSqrt(MatrixRT M){
std::cout << "matrixSqrt not implemented!!!" << std::endl;//implement this
return M;
}
static double lameMu(double E, double nu){
return 0.5 * 1.0/(1.0 + nu) * E;
}
static double lameLambda(double E, double nu){
return nu/(1.0-2.0*nu) * 1.0/(1.0+nu) * E;
}
static bool isInRotatedPlane(double phi, double x1, double x2){
return cos(phi)*x1 + sin(phi)*x2 > 0;
}
/*
template<double phi>
static bool isInRotatedPlane(double x1, double x2){
return cos(phi)*x1 + sin(phi)*x2 > 0;
}*/
}
// OPTIONAL H1-Seminorm ...
/*
template<class VectorCT>
double semi_H1_vectorScalarProduct(VectorCT& coeffVector1, VectorCT& coeffVector2)
{
double ret(0);
auto localView = basis_.localView();
for (const auto& e : elements(basis_.gridView()))
{
localView.bind(e);
auto geometry = e.geometry();
const auto& localFiniteElement = localView.tree().child(0).finiteElement();
const auto nSf = localFiniteElement.localBasis().size();
int order = 2*(dim*localFiniteElement.localBasis().order()-1);
const QuadratureRule<double, dim>& quad = QuadratureRules<double, dim>::rule(e.type(), order);
for (const auto& quadPoint : quad)
{
double elementScp(0);
auto pos = quadPoint.position();
const auto jacobian = geometry.jacobianInverseTransposed(pos);
const double integrationElement = geometry.integrationElement(pos);
std::vector<FieldMatrix<double,1,dim> > referenceGradients;
localFiniteElement.localBasis().evaluateJacobian(pos, referenceGradients);
std::vector< VectorRT > gradients(referenceGradients.size());
for (size_t i=0; i< gradients.size(); i++)
jacobian.mv(referenceGradients[i][0], gradients[i]);
for (size_t i=0; i < nSf; i++)
for (size_t j=0; j < nSf; j++)
for (size_t k=0; k < dimworld; k++)
for (size_t l=0; l < dimworld; l++)
{
MatrixRT defGradient1(0);
defGradient1[k] = gradients[i];
MatrixRT defGradient2(0);
defGradient2[l] = gradients[j];
size_t localIdx1 = localView.tree().child(k).localIndex(i);
size_t globalIdx1 = localView.index(localIdx1);
size_t localIdx2 = localView.tree().child(l).localIndex(j);
size_t globalIdx2 = localView.index(localIdx2);
double scp(0);
for (int ii=0; ii<dimworld; ii++)
for (int jj=0; jj<dimworld; jj++)
scp += coeffVector1[globalIdx1] * defGradient1[ii][jj] * coeffVector2[globalIdx2] * defGradient2[ii][jj];
elementScp += scp;
}
ret += elementScp * quadPoint.weight() * integrationElement;
} //qp
} //e
return ret;
}*/
/*
class BiotStrainApprox
{
// E_h = h^{-1} (R^T F_h - Id)
//
//E_h = (U + K e_cs, 0, 0)
//
Func2Tensor E_a = [] (const Domain& z) //extra Klasse
{
return biotStrainApprox({1, 0, 0}, {0, 0, 0}, {0, z[1], z[2]}); //MatrixRT{{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
};
// twist in x2-x3 plane E_K1 = sym (e1 x (0,x2,x3)^T ot e1)
Func2Tensor E_K1 = [] (const Domain& z)
{
return biotStrainApprox({0, 0, 0}, {1, 0, 0}, {0, z[1], z[2]}); //MatrixRT{{0.0,-0.5*z[2], 0.5*z[1]}, {-0.5*z[2], 0.0 , 0.0 }, {0.5*z[1],0.0,0.0}};
};
// bend strain in x1-x2 plane E_K2 = sym (e2 x (0,x2,x3)^T ot e1)
Func2Tensor E_K2 = [] (const Domain& z)
{
return biotStrainApprox({0, 0, 0}, {0, 1, 0}, {0, z[1], z[2]}); //MatrixRT{{z[2], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0}};
};
// bend strain in x1-x3 plane E_K3 = sym (e3 x (0,x2,x3)^T ot e1)
Func2Tensor E_K3 = [] (const Domain& z)
{
return biotStrainApprox({0, 0, 0}, {0, 0, 1}, {0, z[1], z[2]}); //MatrixRT{{-z[1], 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
};
};
*/
#endif
#ifndef DUNE_MICROSTRUCTURE_HH
#define DUNE_MICROSTRUCTURE_HH
// add your classes here
#endif // DUNE_MICROSTRUCTURE_HH
#ifndef DUNE_REDUCEDROD_MICROSTRUCTUREDRODGRID_HH
#define DUNE_REDUCEDROD_MICROSTRUCTUREDRODGRID_HH
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/onedgrid.hh>
#include <dune/functions/functionspacebases/powerbasis.hh>
#include <dune/functions/functionspacebases/lagrangebasis.hh>
using namespace Dune;
using namespace Functions::BasisBuilder;
class MicrostructuredRodGrid {
public:
//static const int orderFE_Ce = 1;
static const int dim = 3;
static const int nCompo = 3;
using CellGridType = YaspGrid< dim, EquidistantOffsetCoordinates< double, dim>>;
using Rod1DGridType = OneDGrid;
using Rod3DGridType = CellGridType;
using IsometricRodBasisType = Functions::LagrangeBasis<Rod1DGridType::LeafGridView, 1>;
protected:
const double width_;
const double len_;
const double eps_;
const double h_; //thickness h könnte auch in plotmethoden vorkommen und Querschnitt bleibt skaliert
const std::array<int,dim> nE_Ce_;
const FieldVector<double,dim> bboxL_Ce_;
const FieldVector<double,dim> bboxR_Ce_;
const int nE_R1D_;
const std::array<int,dim> nE_R3D_;
const FieldVector<double,dim> bboxL_R3D_;
const FieldVector<double,dim> bboxR_R3D_;
const CellGridType grid_Ce_;
const Rod1DGridType grid_R1D_;
const Rod3DGridType grid_R3D_;
const IsometricRodBasisType basis_IsoRod_;
public:
// Constructor
MicrostructuredRodGrid( const double width,
const double len,
const double eps,
const double h,
const std::array<int,dim> nE_Ce):
width_(width),
len_(len),
eps_(eps),
h_(h),
nE_Ce_(nE_Ce),
bboxL_Ce_({0.0, -width/2.0, -width/2.0}),
bboxR_Ce_({1.0, width/2.0, width/2.0}),
nE_R1D_(int( (len *nE_Ce[0])/ eps) ),
//nE_R3D_({nE_R1D_, int(double(nE_Ce[1])/h), int(double(nE_Ce[2])/h)}),
nE_R3D_({nE_R1D_, nE_Ce[1], nE_Ce[2]}),
bboxL_R3D_({0, h*bboxL_Ce_[1], h*bboxL_Ce_[2] }),
bboxR_R3D_({len, h*bboxR_Ce_[1], h*bboxR_Ce_[2] }),
grid_Ce_(bboxL_Ce_, bboxR_Ce_, nE_Ce),
grid_R1D_(nE_R1D_, 0, len),
grid_R3D_(bboxL_R3D_, bboxR_R3D_, nE_R3D_),
basis_IsoRod_(grid_R1D_.leafGridView())
{}
// Getter
double getWidth() {return width_;}
double getLen() {return len_;}
double getEps() {return eps_;}
double getH() {return h_;}
std::array<int,dim> getNECell() {return nE_Ce_;}
FieldVector<double,dim> getBboxLCell() {return bboxL_Ce_;}
FieldVector<double,dim> getBboxRCell() {return bboxR_Ce_;}
const int getNERod1D(){return nE_R1D_;}
std::array<int,dim> getNERod3D() {return nE_R3D_;}
FieldVector<double,dim> getBboxLRod3D() {return bboxL_R3D_;}
FieldVector<double,dim> getBboxRRod3D() {return bboxR_R3D_;}
const CellGridType & getCellGrid() {return grid_Ce_;}
const Rod1DGridType & getRod1DGrid() {return grid_R1D_;}
const Rod3DGridType & getRod3DGrid() {return grid_R3D_;}
const IsometricRodBasisType* getIsometricRodBasis() {return &basis_IsoRod_;}
//return gridViews
//Rod1DGridType copyRod1DGrid() {Rod1DGridType grid = grid_R1D_; return grid;}
}; // end class
#endif
\ No newline at end of file
This diff is collapsed.
#ifndef DUNE_MICROSTRUCTURE_PRESTRAINIMP_HH
#define DUNE_MICROSTRUCTURE_PRESTRAINIMP_HH
// #include <dune/microstructure/microstructuredrodgrid.hh>
#include <dune/grid/uggrid.hh>
#include <dune/grid/yaspgrid.hh>
//template<class MicrostructuredRodGrid> reicht include
using namespace Dune;
class PrestrainImp {
public:
static const int dim = 3;
static const int nCompo = 3;
// using GridType_Ce = typename MicrostructuredRodGrid::CellGridType;
using CellGridType = YaspGrid< dim, EquidistantOffsetCoordinates< double, dim>>;
using GridView = CellGridType::LeafGridView;
using Domain = GridView::Codim<0>::Geometry::GlobalCoordinate;
using MatrixRT = FieldMatrix< double, nCompo, nCompo>;
using Func2Tensor = std::function< MatrixRT(const Domain&) >;
// using Domain = typename GridType_Ce::LeafGridView::template Codim<0>::Geometry::GlobalCoordinate;
// using MatrixRT = FieldMatrix< double, nCompo, nCompo>;
// using Func2Tensor = std::function< MatrixRT(const Domain&) >;
protected:
double p1, p2, theta;
double width; //cell geometry
public:
PrestrainImp(double p1, double p2, double theta, double width) : p1(p1), p2(p2), theta(theta), width(width){}
Func2Tensor getPrestrain(unsigned int imp)
{
using std::pow;
using std::abs;
using std::sqrt;
using std::sin;
using std::cos;
if (imp==1)
{
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}};
};
std::cout <<" Prestrain Type: 1 "<< std::endl;
return B1_;
}
else if (imp==2)
{
Func2Tensor B2_ = [this] (const Domain& x) { // Bilayer with one rectangular Fiber & ISOTROPIC PRESSURE
if (abs(x[0]) < (theta/2) && x[2] < 0 && x[2] > -(1.0/2.0) )
return MatrixRT{{p1, 0.0 , 0.0}, {0.0, p1, 0.0}, {0.0, 0.0, p1}};
else
return MatrixRT{{0.0, 0.0 , 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
};
std::cout <<" Prestrain Type: 2 "<< std::endl;
return B2_;
}
// TODO ANISOTROPIC PRESSURE
// else if (imp==2)
// {
//
// Func2Tensor B2_ = [this] (const Domain& z)
// {
// auto pi = std::acos(-1.0);
// double beta = pi/4.0 + pi/4.0*z[1]; //z[1]=x3
// MatrixRT Id(0);
// for (int i=0;i<nCompo;i++)
// Id[i][i]=1.0;
// MatrixRT pressure = Id;
// pressure *= 1.0/6.0;
// MatrixRT n_ot_n = {
// {cos(beta)*cos(beta), 0.0, cos(beta)*sin(beta)},
// {0.0, 0.0, 0.0 },
// {cos(beta)*sin(beta), 0.0, sin(beta)*sin(beta)}
// };
// n_ot_n*=0.5;
// pressure += n_ot_n;
// pressure *= this->a;
// return pressure;
// };
// return B2_;
// }
}
};
#endif
template<class Basis>
class TestClass {
public:
static const int nCompo = 3;
using GridView = typename Basis::GridView;
using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate;
using MatrixRange = FieldMatrix< double, nCompo, nCompo>;
using Func2Tensor = std::function< MatrixRange(const Domain&) >;
const Basis& basis_;
Func2Tensor prestress_;
MatrixRange evaluateZero()
{
auto preStressGrid = Functions::makeGridViewFunction(prestress_, basis_.gridView());
return prestress_({0,0,0});
}
TestClass(const Basis& basis, Func2Tensor prestress) : basis_(basis), prestress_(prestress) {}
};
/*
template <class Basis, class GridF1, class GridF2> //, class GridScalar> //, class LocalScalar, class Local2Tensor> // LocalFunction derived from basis?
class TestClass {
using GridView = typename Basis::GridView;
using Domain = typename GridView::template Codim<0>::Geometry::GlobalCoordinate;
using ScalarRange = FieldVector< double, 1>;
using FuncScalar = std::function< ScalarRange(const Domain&) >;
private:
//const int dim = 3;
const Basis basis_;
const ParameterTree& parameterSet_;
const GridF1& mu1_;
const GridF2& mu2_;
std::map<int,int> perIndexMap_;
public:
TestClass(const Basis& basis,
const GridF1& mu
const ParameterTree& parameterSet)
: basis_(basis),
mu1_(mu),
mu2_(mu)
{}
};
*/