1#ifndef CREATE_STRUCTUREMODEL__HH
2#define CREATE_STRUCTUREMODEL__HH
4#include <dune/composites/Setup/Cijkl.hh>
5#include <dune/composites/Setup/Region.hh>
7#include <dune/composites/Driver/Solvers/solver_info.hh>
8#include <dune/composites/Driver/Solvers/solvers.hh>
24 typedef Dune::YaspGrid<3,Dune::TensorProductCoordinates<double,3>> YGRID;
25 typedef YGRID::LeafGridView YGV;
26 typedef Dune::FieldVector<double,3> FieldVec;
27 typedef Dune::FieldVector<double,6> Tensor2;
28 typedef Dune::FieldMatrix<double,6,6> Tensor4;
33 std::array<std::vector<double>,3> coords;
37 Dune::MPIHelper& helper;
38 std::vector<Tensor4> baseTensor;
42 std::vector<Material> myMaterials;
43 std::vector<Region>
R;
47 std::vector<Tensor4>
C;
60 std::vector<std::vector<double>> sig;
63 std::string vtk_displacement_output;
64 std::string vtk_stress_output;
65 std::string vtk_properties_output;
71 SolverInfo solverParameters;
75 bool failureCriterionDefined;
79 double gravity = 9.80665;
87 if (helper.size() > 1){
95 intOrder = config.get<
int>(
"fe.intOrder",5);
101 vtk_displacement_output =
"baseModel_displacement";
102 vtk_stress_output =
"baseModel_stress";
103 vtk_properties_output =
"baseModel_properties";
105 residualHeat =
false;
107 failureCriterionDefined =
false;
115 computeElasticTensors();
119 void inline sizeStressVector(
int nel){
121 for (
unsigned int i = 0; i < sig.size(); i++){
126 void inline setStress(
int id, Dune::FieldVector<double,6>& element_stress){
127 for (
int i = 0; i < 6; i++){
128 sig[id][i] = element_stress[i];
132 Dune::FieldVector<double,6>
inline getStress(
int id){
133 Dune::FieldVector<double,6> element_stress;
134 for (
int i = 0; i < 6; i++){
135 element_stress[i] = sig[id][i];
137 return element_stress;
140 int inline getIntOrder()
const {
149 int inline whichRegion(
const FieldVec& x){
153 for (
unsigned int k = 0; k <
R.size(); k++){
155 if (x[0] < Lx && flag ==
false){ ans = k; flag =
true; }
160 int inline whichLayer(FieldVec& x,
unsigned int r){
161 assert(r <
R.size());
165 for (
unsigned int k = 0; k <
R[r].layers.size(); k++){
166 z +=
R[r].layers[k].getThickness();
167 if (x[2] < z && flag ==
false){ ans = k; flag =
true; }
175 if(residualHeat !=
false){
176 double deltaT = -160.;
177 double alpha11 = -0.342 * 1e-6;
178 double alpha22 = 25.8 * 1e-6;
179 double alpha33 = 25.8 * 1e-6;
180 double alpharesin = 25.8 * 1e-6;
181 if(getMaterialTypeFromElement(
id) == 0){
182 f[0] = alpharesin*deltaT;
183 f[1] = alpharesin*deltaT;
184 f[2] = alpharesin*deltaT;
187 f[0] = alpha11*deltaT;
188 f[1] = alpha22*deltaT;
189 f[2] = alpha33*deltaT;
194 inline void evaluateWeight(Dune::FieldVector<double,3>& f,
int id)
const{
196 f[2] = - gravity * myMaterials[pg].density;
199 inline void setPressure(
double q_new) {
204 inline void evaluateNeumann(
const Dune::FieldVector<double,3> &x,Dune::FieldVector<double,3>& h,
const Dune::FieldVector<double,3>& normal)
const{
209 void inline setSolver(){
211 if (helper.size() > 1){
216 int inline getElements(
int i){
236 std::vector<int>
nel(3);
238 for (
int i = 0; i < 3; i++){
239 double h = 1. /
nel[i];
240 coords[i].resize(
nel[i] + 1);
242 for (
int j = 1; j <=
nel[i]; j++){
243 coords[i][j] = coords[i][j-1] + h;
258 ifstream csvFile(pathToCsv);
259 if(! csvFile)
throw std::runtime_error(
"Could not open file " + pathToCsv);
266 getline(csvFile, line);
267 istringstream lineStream(line);
269 for (
int j = 0; j < 2; j++){
271 getline(lineStream, item,
',');
272 if(helper.rank() == 0) std::cout << item << std::endl;
275 numRegions = atof(item.c_str());
276 if(helper.rank() == 0) std::cout <<
"Number of Regions = " << numRegions << std::endl;
277 R.resize(numRegions);
279 getline(csvFile, line);
280 istringstream lS2(line);
283 getline(lS2, item,
',');
284 getline(lS2, item,
',');
285 maxPly = atof(item.c_str());
286 if(helper.rank() == 0) std::cout <<
"maxPly = " << maxPly << std::endl;
288 getline(csvFile, line);
289 istringstream lS3(line);
290 for (
int j = 0; j < 4; j++){
292 getline(lS3, item,
',');
297 if(helper.rank() == 0) std::cout <<
"periodic = " <<
periodic << std::endl;
299 for(
int j = 0; j < numRegions; j++){
302 R[j].setNumLayers(maxPly);
303 getline(csvFile, line); getline(csvFile, line);
304 int numParameters = 1;
305 istringstream lS4(line);
306 for (
int ii = 0; ii < numParameters; ii++){
307 getline(lS4, item,
',');
309 R[j].setType(atof(item.c_str()));
310 numParameters =
R[j].numParameters;
313 R[j].setParameter(ii-1,atof(item.c_str()));
317 for (
int k = 0; k < maxPly; k++){
319 getline(csvFile, line);
320 istringstream lS5(line);
321 getline(lS5,item,
',');
322 R[j].layers[k].setElements(atof(item.c_str()));
325 getline(lS5,item,
',');
328 R[j].layers[k].setMaterial(atof(item.c_str()) );
329 getline(lS5,item,
',');
330 R[j].layers[k].setThickness(atof(item.c_str()));
333 getline(lS5,item,
',');
334 R[j].layers[k].setOrientation(atof(item.c_str()));
342 void inline GeometryBuilder(){
344 if(helper.rank() == 0) std::cout <<
"=== Building Geometry" << std::endl;
346 Dune::FieldVector<double,3> origin(0.0);
349 int numRegions =
R.size();
352 int nely =
R[0].nel[1];
354 for (
int i = 0; i < numRegions;i++){
356 assert(
R[i].
nel[1] == nely);
359 if(helper.rank() == 0) std::cout <<
"Elements in x direction " << std::endl;
361 coords[0].resize(nelx + 1);
362 coords[0][0] = origin[0];
366 for (
int i = 0; i < numRegions; i++){
367 double hx =
R[i].L[0] /
R[i].nel[0];
368 for (
int j = 0; j <
R[i].nel[0]; j++){
369 coords[0][k] = coords[0][k-1] + hx;
375 coords[1].resize(nely + 1);
376 coords[1][0] = origin[0];
377 double hy =
R[0].L[1] /
R[0].nel[1];
378 for (
int j = 1; j <
R[0].nel[1] + 1; j++){
379 coords[1][j] = coords[1][j-1] + hy;
385 for (
unsigned int i = 0; i <
R[0].layers.size(); i++){
387 nelz +=
R[0].layers[i].getElements();
389 coords[2].resize(nelz + 1);
390 coords[2][0] = origin[2];
393 for (
unsigned int i = 0; i <
R[0].layers.size(); i++){
394 double hz =
R[0].layers[i].getThickness() /
R[0].layers[i].getElements();
395 for (
int k = 0; k <
R[0].layers[i].getElements(); k++){
397 coords[2][e] = coords[2][e-1] + hz;
400 R[0].L[2] = coords[2][e];
404 int inline getSizeCoords(
int i){
return coords[i].size(); }
407 void setUpMaterials(){
412 myMaterials[0].setType(0);
413 myMaterials[0].setProp(0,10000.);
414 myMaterials[0].setProp(1,0.35);
415 myMaterials[0].setDensity(1.57e-5);
418 myMaterials[1].setType(1);
419 myMaterials[1].setProp(0,162000.);
420 myMaterials[1].setProp(1,10000.);
421 myMaterials[1].setProp(2,10000.);
422 myMaterials[1].setProp(3,0.35);
423 myMaterials[1].setProp(4,0.35);
424 myMaterials[1].setProp(5,0.49);
425 myMaterials[1].setProp(6,5200.);
426 myMaterials[1].setProp(7,5200.);
427 myMaterials[1].setProp(8,3500.);
428 myMaterials[1].setDensity(1.57e-5);
431 myMaterials[2].setType(0);
432 myMaterials[2].setProp(0,10000000.);
433 myMaterials[2].setProp(1,0.35);
434 myMaterials[2].setDensity(1.57e-5);
438 double inline FailureCriteria(Dune::FieldVector<double,6>& stress)
const{
442 template <
class GV,
class GV2>
443 void computeTensorsOnGrid(
const GV& gv,
const GV2& gv2){
445 typedef typename GV::Traits::template Codim<0>::Iterator ElementIterator;
446 auto is = gv.indexSet();
447 C.resize(gv.size(0));
450 auto it2 = gv2.template begin<0>();
452 for (ElementIterator it = gv.template begin<0>(); it!=gv.template end<0>(); ++it)
454 int id = is.index(*it);
456 C[id] = TensorRotation(baseTensor[pg],
rot123[
id],2);
461 FieldVec
inline gridTransformation(
const FieldVec & x)
const{
467 std::array<int, 3>
inline GridPartition(){
469 std::array<int, 3> Partitioning;
470 std::fill(Partitioning.begin(),Partitioning.end(), 1);
474 void inline setPG(
const YGV& ygv){
476 rot123.resize(ygv.size(0));
478 for (
const auto& eit : elements(ygv)){
479 int id = ygv.indexSet().index(eit);
480 auto point = eit.geometry().center();
483 int theRegion = whichRegion(point);
484 int theLayer = whichLayer(point,theRegion);
485 elemIndx2PG[id] =
R[theRegion].layers[theLayer].getMaterial();
486 rot123[id] =
R[theRegion].layers[theLayer].getOrientation();
487 for(
int i = 0; i < eit.geometry().corners(); i++){
488 auto pc = eit.geometry().corner(i);
497 int inline getMaterialType(
int whichMaterial){
499 return myMaterials[whichMaterial].Type;
503 int inline setPhysicalGroup(FieldVec& x){
507 void inline computeElasticTensors(){
511 baseTensor[i] = Cijkl(myMaterials[i]);
516 Tensor4 TensorRotation(Tensor4& baseC,
double theta,
int i_dim)
const
518 Tensor4 locC = baseC;
519 Tensor4 R2(0.0),R2T(0.0);
522 double c = cos(theta*M_PI/180.0);
523 double s = sin(theta*M_PI/180.0);
524 Dune::FieldMatrix<double,3,3> A;
525 if(i_dim == 2) A = {{c,s,0},{-s,c,0},{0,0,1}};
526 if(i_dim == 1) A = {{c,0,-s},{0,1,0},{s,0,c}};
527 if(i_dim == 0) A = {{1,0,0},{0,c,s},{0,-s,c}};
531 transpose<Tensor4,6>(R2,R2T);
534 locC.leftmultiply(R2);
535 locC.rightmultiply(R2T);
539 Tensor4 TensorRotationLeft(Tensor4& C_local,
double theta,
int i_dim)
const{
540 Tensor4 locC = C_local;
541 Tensor4 R2(0.0),R2T(0.0);
544 double c = cos(theta*M_PI/180.0);
545 double s = sin(theta*M_PI/180.0);
546 Dune::FieldMatrix<double,3,3> A;
547 if(i_dim == 2) A = {{c,s,0},{-s,c,0},{0,0,1}};
548 if(i_dim == 1) A = {{c,0,-s},{0,1,0},{s,0,c}};
549 if(i_dim == 0) A = {{1,0,0},{0,c,s},{0,-s,c}};
555 locC.leftmultiply(R2);
559 Tensor4 TensorRotationRight(Tensor4& C_local,
double theta,
int i_dim)
const{
560 Tensor4 locC = C_local;
561 Tensor4 R2(0.0),R2T(0.0);
564 double c = cos(theta*M_PI/180.0);
565 double s = sin(theta*M_PI/180.0);
566 Dune::FieldMatrix<double,3,3> A;
567 if(i_dim == 2) A = {{c,s,0},{-s,c,0},{0,0,1}};
568 if(i_dim == 1) A = {{c,0,-s},{0,1,0},{s,0,c}};
569 if(i_dim == 0) A = {{1,0,0},{0,c,s},{0,-s,c}};
573 transpose<Tensor4,6>(R2,R2T);
576 locC.rightmultiply(R2T);
582 Tensor4 getMatrix(Dune::FieldMatrix<double,3,3> A)
const{
584 R[0][0] = A[0][0]*A[0][0];
R[0][1] = A[0][1]*A[0][1];
R[0][2] = A[0][2]*A[0][2];
585 R[1][0] = A[1][0]*A[1][0];
R[1][1] = A[1][1]*A[1][1];
R[1][2] = A[1][2]*A[1][2];
586 R[2][0] = A[2][0]*A[2][0];
R[2][1] = A[2][1]*A[2][1];
R[2][2] = A[2][2]*A[2][2];
588 R[0][3] = 2.0*A[0][1]*A[0][2];
R[0][4] = 2.0*A[0][0]*A[0][2];
R[0][5] = 2.0*A[0][0]*A[0][1];
589 R[1][3] = 2.0*A[1][1]*A[1][2];
R[1][4] = 2.0*A[1][0]*A[1][2];
R[1][5] = 2.0*A[1][0]*A[1][1];
590 R[2][3] = 2.0*A[2][1]*A[2][2];
R[2][4] = 2.0*A[2][0]*A[2][2];
R[2][5] = 2.0*A[2][0]*A[2][1];
592 R[3][0] = A[1][0]*A[2][0];
R[3][1] = A[1][1]*A[2][1];
R[3][2] = A[1][2]*A[2][2];
593 R[4][0] = A[0][0]*A[2][0];
R[4][1] = A[0][1]*A[2][1];
R[4][2] = A[0][2]*A[2][2];
594 R[5][0] = A[0][0]*A[1][0];
R[5][1] = A[0][1]*A[1][1];
R[5][2] = A[0][2]*A[1][2];
596 R[3][3] = A[1][1]*A[2][2]+A[1][2]*A[2][1];
R[3][4] = A[1][0]*A[2][2]+A[1][2]*A[2][0];
R[3][5] = A[1][0]*A[2][1]+A[1][1]*A[2][0];
597 R[4][3] = A[0][1]*A[2][2]+A[2][1]*A[0][2];
R[4][4] = A[0][0]*A[2][2]+A[2][0]*A[0][2];
R[4][5] = A[2][0]*A[0][1]+A[2][1]*A[0][0];
598 R[5][3] = A[0][1]*A[1][2]+A[0][2]*A[1][1];
R[5][4] = A[0][0]*A[1][2]+A[0][2]*A[1][0];
R[5][5] = A[0][0]*A[1][1]+A[0][1]*A[1][0];
605 Tensor4
inline getElasticTensor(
int id)
const {
return C[id]; }
607 std::vector<double> returnTheta(
const FieldVec& x)
const{
610 FieldVec xph = x; xph[0] += h/2.;
611 FieldVec xmh = x; xmh[0] -= h/2.;
612 y = gridTransformation(xph);
613 yph = gridTransformation(xmh);
614 auto angle = atan2((yph[2]-y[2])/h,(yph[0]-y[0])/h);
615 std::vector<double> theta(3);
640 double inline getMaterialTypeFromElement(
int id)
const{
642 return myMaterials[pg].Type;
645 double inline getOrientation(
int id)
const {
return rot123[id];}
647 template<
class GO,
class U,
class GFS,
class C,
class MBE,
class GV>
648 void inline postprocess(
const GO& go, U& u,
const GFS& gfs,
const C& cg,
const GV gv, MBE& mbe){
652 template<
class GO,
class V,
class GFS,
class C,
class CON,
class MBE,
class LOP>
653 bool inline solve(GO& go, V& u,
const GFS& gfs,
C& cg, CON& constraints, MBE& mbe, LOP& lop){
657 if(gfs.gridView().comm().size() > 1){
658 if(solverParameters.preconditioner ==
"GenEO"){
659 typedef Dune::Geneo::CG_GenEO<V,GFS,GO,LOP,CON,MBE> GenEO;
660 int cells = std::pow(gfs.gridView().size(0),1./3.);
661 GenEO mysolver(u,gfs,lop,constraints,mbe,solverParameters,helper, cells);
665 if(solverParameters.preconditioner ==
"OneLevel_AdditiveSchwarz"){
666 typedef Dune::PDELab::ISTLBackend_OVLP_CG_UMFPack<GFS, C> PAR_UMF;
667 PAR_UMF ls(gfs,cg,solverParameters.MaxIt,solverParameters.verb);
668 Dune::PDELab::StationaryLinearProblemSolver<GO,PAR_UMF,V> slp(go,ls,u,solverParameters.KrylovTol);
673 if(solverParameters.solver ==
"Hypre"){
675 typedef typename GO::Jacobian Matrix;
680 HypreSolver<GFS, Matrix, V> solver(gfs,u,a,b, solverParameters.KrylovTol);
686 if(gfs.gridView().comm().size() == 1){
687 if(solverParameters.solver ==
"UMFPack"){
689 typedef Dune::PDELab::ISTLBackend_SEQ_UMFPack SEQ_UMF;
691 Dune::PDELab::StationaryLinearProblemSolver<GO, SEQ_UMF,V> slp(go,ls,u,1e-6);
694 if(gfs.gridView().rank() == 0) std::cout <<
"SEQ_UMFPack solver not available" << std::endl;
698 if(solverParameters.preconditioner ==
"AMG"){
699 typedef Dune::PDELab::ISTLBackend_SEQ_CG_AMG_SSOR<GO> SEQ_CG_AMG_SSOR;
701 Dune::PDELab::StationaryLinearProblemSolver<GO,SEQ_CG_AMG_SSOR,V> slp(go,ls,u,
tolerance);
structuredGridModel class.
Definition: baseStructuredGridModel.hh:20
int solver_tolerance
Variable which controls solver type (UMFPack for sequential and GENEO for parallel)
Definition: baseStructuredGridModel.hh:52
bool isMPC(FieldVec &x)
A function which returns whether a point is constrained by a multi-point-constraint.
Definition: baseStructuredGridModel.hh:630
void LayerCake()
A member taking which constructs the base layered laminate in untransformed coordinates.
Definition: baseStructuredGridModel.hh:228
int Krylov_Verb
Tolerance of Solver (ignored for a direct solver)
Definition: baseStructuredGridModel.hh:53
std::vector< double > rot123
std::vector containing information of each material defined
Definition: baseStructuredGridModel.hh:46
bool verbosity
Vector storing elastic tensor within each element.
Definition: baseStructuredGridModel.hh:49
void setThermal(bool t)
returns true when thermal strain is applied
Definition: baseStructuredGridModel.hh:145
int Krylov_Max_It
Variable Controlling Verbosity of Krylov Solver.
Definition: baseStructuredGridModel.hh:54
void LayerCakeFromFile(string pathToCsv)
Function to read LayerCake from File.
Definition: baseStructuredGridModel.hh:256
std::vector< Region > R
std::vector containing information of each material defined
Definition: baseStructuredGridModel.hh:43
std::vector< int > nel
Gaussian order of integration (default value is 5)
Definition: baseStructuredGridModel.hh:67
std::bitset< 3 > periodic
Array which stores periodicity of grid in each of the 3 dimensions, default value are set to all fals...
Definition: baseStructuredGridModel.hh:36
int solver_type
Tolerance of iterative solver.
Definition: baseStructuredGridModel.hh:51
void evaluateNeumann(const Dune::FieldVector< double, 3 > &x, Dune::FieldVector< double, 3 > &h, const Dune::FieldVector< double, 3 > &normal) const
function which evaluates the Neumann boundary conditions at the point x
Definition: baseStructuredGridModel.hh:204
double q
Instance of SolverInfo to define solver parameters and store solver results e.g. iterations,...
Definition: baseStructuredGridModel.hh:73
int overlap
Size of overlap between subdomains for domain decomposition.
Definition: baseStructuredGridModel.hh:31
bool setUp_Required
Boolean variable which indicates if run is parallel or not, this later will allow to run multiple sol...
Definition: baseStructuredGridModel.hh:69
std::vector< int > elemIndx2PG
std::vector containing information of each Region
Definition: baseStructuredGridModel.hh:45
int solver_verb
Variable define max iterations.
Definition: baseStructuredGridModel.hh:55
int numMaterials
Number of Different types of materials defined for applications.
Definition: baseStructuredGridModel.hh:41
std::vector< Tensor4 > C
Vector defining rotation of ply in material coordinates.
Definition: baseStructuredGridModel.hh:47
bool sigResized
Variable if stress is plotted out in vtk format.
Definition: baseStructuredGridModel.hh:62
void evaluateHeat(Tensor2 &f, int id) const
Function which evaluates the thermal stress tensor sig_thermal on an element.
Definition: baseStructuredGridModel.hh:173
double evaluateDirichlet(const FieldVec &x, int dof) const
returns the Dirichlet boundary value at a point for the degree of freedom dof.
Definition: baseStructuredGridModel.hh:635
bool isParallel
Number of elements in each direction.
Definition: baseStructuredGridModel.hh:68
double tolerance
Variable controls level of output to interfacea.
Definition: baseStructuredGridModel.hh:50
baseStructuredGridModel(Dune::MPIHelper &helper_, bool GenEO=false)
The main constructor.
Definition: baseStructuredGridModel.hh:84
bool isDirichlet(FieldVec &x, int dof)
Definition: baseStructuredGridModel.hh:622
std::vector< double > stackSeq
Set whether to use residual heat stresses, default false.
Definition: baseStructuredGridModel.hh:59