Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
FE_def.hpp
1#ifndef FE_DEF_hpp
2#define FE_DEF_hpp
3
4#ifdef FEDD_HAVE_ACEGENINTERFACE
5#include <aceinterface.hpp>
6#endif
7
8#include "FE_decl.hpp"
9
18
19
20int MMAInitialisationCode[]={
21 0,0
22};
23
24
25using Teuchos::reduceAll;
26using Teuchos::REDUCE_SUM;
27using Teuchos::outArg;
28
29namespace FEDD {
30DataElement::DataElement():
31ht_(1,0.),
32hp_(1,0.)
33{
34
35}
36
37DataElement::DataElement(int size):
38ht_(size,0.),
39hp_(size,0.)
40{
41
42}
43
44std::vector<double> DataElement::getHp()
45{
46 return hp_;
47}
48
49std::vector<double> DataElement::getHt()
50{
51 return ht_;
52}
53
54void DataElement::setHp( double* ht )
55{
56 for (int i=0; i<hp_.size(); i++)
57 hp_[i] = ht[i];
58}
59
60
61template <class SC, class LO, class GO, class NO>
62FE<SC,LO,GO,NO>::FE(bool saveAssembly):
63domainVec_(0),
64es_(),
65setZeros_(false),
66myeps_(),
67ed_(0),
68saveAssembly_(saveAssembly)
69{
70}
71
72template <class SC, class LO, class GO, class NO>
73void FE<SC,LO,GO,NO>::addFE(DomainConstPtr_Type domain){
74
75 if (saveAssembly_){
76 DomainPtr_Type domainNC = Teuchos::rcp_const_cast<Domain_Type>( domain );
77 domainNC->initializeFEData();
78 }
79 domainVec_.push_back(domain);
80
81}
82
83template <class SC, class LO, class GO, class NO>
84void FE<SC,LO,GO,NO>::doSetZeros(double eps){
85
86 setZeros_ = true;
87 myeps_ = eps;
88
89}
90
91template <class SC, class LO, class GO, class NO>
92void FE<SC,LO,GO,NO>::applyBTinv( vec3D_dbl_ptr_Type& dPhiIn,
93 vec3D_dbl_Type& dPhiOut,
94 SmallMatrix<SC>& Binv){
95 UN dim = Binv.size();
96 for (UN w=0; w<dPhiIn->size(); w++){
97 for (UN i=0; i < dPhiIn->at(w).size(); i++) {
98 for (UN d1=0; d1<dim; d1++) {
99 for (UN d2=0; d2<dim; d2++) {
100 dPhiOut[w][i][d1] += dPhiIn->at(w).at(i).at(d2) * Binv[d2][d1];
101 }
102 }
103 }
104 }
105}
106
118
119// Check the order of chemistry and solid in system matrix
120/*template <class SC, class LO, class GO, class NO>
121void FE<SC,LO,GO,NO>::globalAssembly(std::string ProblemType,
122 int dim,
123 int degree,
124 MultiVectorPtr_Type sol_rep,
125 BlockMatrixPtr_Type &A,
126 BlockMultiVectorPtr_Type &resVec,
127 ParameterListPtr_Type params,
128 std::string assembleMode,
129 bool callFillComplete,
130 int FELocExternal){
131
132 int problemSize = domainVec_.size(); // Problem size, as in number of subproblems
133
134 // Depending on problem size we extract necessary information
135
138 int numChem=3;
139 if(FETypeChem == "P2"){
140 numChem=6;
141 }
142 if(dim==3){
143 numChem=4;
144 if(FETypeChem == "P2")
145 numChem=10;
146 }
147 int numSolid=3;
148 if(FETypeSolid == "P2")
149 numSolid=6;
150
151 if(dim==3){
152 numSolid=4;
153 if(FETypeSolid == "P2")
154 numSolid=10;
155 }
156
157 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp( new BlockMultiVector_Type( 2) );
158
159 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
160 for(int i=0; i< problemSize; i++){
161 int numNodes=0.;
162 if(domainVec.at(i)->getFEType() == "P2"){
163 numNodes=6;
164 }
165 if(dim==3){
166 numNodes=4;
167 if(domainVec.at(i)->getFEType() == "P2")
168 numNodes=10;
169 }
170 tuple_ssii_Type infoTuple (domainVec.at(i)->getPhysic(),domainVec.at(i)->getFEType(),domainVec.at(i)->getDofs(),numChem);
171 problemDisk->push_back(infoTuple);
172
173 MultiVectorPtr_Type resVec;
174 if(domainVec.at(i)->getDofs() == 1)
175 resVec = Teuchos::rcp( new MultiVector_Type( domainVec_.at(i)->getMapRepeated(), 1 ) );
176 else
177 resVec = Teuchos::rcp( new MultiVector_Type( domainVec_.at(i)->getMapVecFieldRepeated(), 1 ) );
178
179 resVecRep->addBlock(resVec,i);
180
181
182 }
183
184
185 if(assemblyFEElements_.size()== 0){
186 initAssembleFEElements(ProblemType,problemDisk,domainVec_.at(0)->getElementsC(), params,domainVec_.at(0)->getPointsRepeated(),domainVec_.at(0)->getElementMap());
187 }
188 else if(assemblyFEElements_.size() != domainVec_.at(0)->getElementsC()->numberElements())
189 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
190
191 vec_dbl_Type solution_tmp;
192 for (UN T=0; T<assemblyFEElements_.size(); T++) {
193 vec_dbl_Type solution(0);
194 vec_FE_Type elements;
195 for(int i=0; i< problemSize; i++){
196 solution_tmp = getSolution(domainVec_.at(i)->getElementsC()->getElement(T).getVectorNodeList(), sol_rep->getBlock(i),domainVec.at(i)->getDofs());
197 solution.insert( solution.end(), solution_tmp.begin(), solution_tmp.end() );
198
199
200 }
201
202 assemblyFEElements_[T]->updateSolution(solution);
203
204 SmallMatrixPtr_Type elementMatrix;
205 vec_dbl_ptr_Type rhsVec;
206
207 if(assembleMode == "Jacobian"){
208 assemblyFEElements_[T]->assembleJacobian();
209
210 elementMatrix = assemblyFEElements_[T]->getJacobian();
211 //elementMatrix->print();
212 assemblyFEElements_[T]->advanceNewtonStep(); // n genereal non linear solver step
213
214 addFeBlockMatrix(A, elementMatrix, domainVec_.at(0)->getElementsC()->getElement(T), problemDisk);
215
216 }
217 if(assembleMode == "Rhs"){
218 assemblyFEElements_[T]->assembleRHS();
219 rhsVec = assemblyFEElements_[T]->getRHS();
220 addFeBlockMv(resVecRep, rhsVec, elementsSolid->getElement(T),elementsChem->getElement(T), dofsSolid,dofsChem);
221
222 }
223
224 }
225 if ( assembleMode == "Jacobian"){
226 for(int probRow = 0; probRow < problemSize; probRow++){
227 for(int probCol = 0; probCol < problemSize; probCol++){
228 MapConstPtr_Type rowMap;
229 MapConstPtr_Type domainMap;
230
231 if(domainVec.at(probRow)->getDofs() == 1)
232 rowMap = domainVec_.at(FElocRow)->getMapUnique();
233 else
234 rowMap = domainVec_.at(probRow)->getMapVecFieldUnique();
235
236 if(domainVec.at(probCol)->getDofs() == 1)
237 domainMap = domainVec_.at(probCol)->getMapUnique()
238 else
239 domainMap = domainVec_.at(probCol)->getMapVecFieldUnique()
240
241 A->getBlock(probRow,probCol)->fillComplete(domainMap,rowMap);
242 }
243 }
245 else if(assembleMode == "Rhs"){
246
247 for(int probRow = 0; probRow < problemSize; probRow++){
248 MapConstPtr_Type rowMap;
249 if(domainVec.at(probRow)->getDofs() == 1)
250 rowMap = domainVec_.at(FElocRow)->getMapUnique();
251 else
252 rowMap = domainVec_.at(probRow)->getMapVecFieldUnique();
253
254 MultiVectorPtr_Type resVecUnique = Teuchos::rcp( new MultiVector_Type( rowMap, 1 ) );
255
256 resVecUnique->putScalar(0.);
257
258 resVecUnique->exportFromVector( resVecRep, true, "Add" );
259
260 resVec->addBlock(resVecUnique,probRow);
261 }
262 }
263
264}*/
265
278/*template <class SC, class LO, class GO, class NO>
279void FE<SC,LO,GO,NO>::addFeBlockMatrix(BlockMatrixPtr_Type &A, SmallMatrixPtr_Type elementMatrix, FiniteElement_vec element, tuple_disk_vec_ptr_Type problemDisk){
280
281 int numDisk = problemDisk->size();
282
283 for(int probRow = 0; probRow < numDisk; probRow++){
284 for(int probCol = 0; probCol < numDisk; probCol++){
285 int dofs1 = std::get<2>(problemDisk->at(probRow));
286 int dofs2 = std::get<2>(problemDisk->at(probCol));
287
288 int numNodes1 = std::get<3>(problemDisk->at(probRow));
289 int numNodes2=std::get<3>(problemDisk->at(probCol));
290
291 int offsetRow= numNodes1*dofs1*probRow;
292 int offsetCol= numNodes1*dofs1*probCol;
294 mapRow = domainVec.at(probRow)->getMapRepeated();
295 mapCol = domainVec.at(probCol)->getMapRepeated();
296
297 Teuchos::Array<SC> value2( numNodes2, 0. );
298 Teuchos::Array<GO> columnIndices2( numNodes2, 0 );
299 for (UN i=0; i < numNodes1; i++){
300 for(int di=0; di<dofs1; di++){
301 GO row =GO (dofs1* mapRow->getGlobalElement( element[probRow].getNode(i) )+di);
302 for(int d=0; d<dofs2; d++){
303 for (UN j=0; j < numNodes2 ; j++) {
304 value2[j] = (*elementMatrix)[offsetRow+i*dofs1+di][offsetCol+j*dofs2+d];
305 columnIndices2[j] =GO (dofs2* mapCol->getGlobalElement( element.getNode(j) )+d);
306 }
307 A->getBlock(probRow,probCol)->insertGlobalValues( row, columnIndices2(), value2() ); // Automatically adds entries if a value already exists
308 }
309 }
310 }
311
312 }
313 }
314}
316*/
317
328/*
329template <class SC, class LO, class GO, class NO>
330void FE<SC,LO,GO,NO>::addFeBlockMv(BlockMultiVectorPtr_Type &res, vec_dbl_ptr_Type rhsVec,tuple_disk_vec_ptr_Type problemDisk, FiniteElement_vec element)
331 int numDisk = problemDisk->size();
332
333 for(int probRow = 0; probRow < numDisk; probRow++){
334 Teuchos::ArrayRCP<SC> resArray_block = res->getBlockNonConst(probRow)->getDataNonConst(0);
335 vec_LO_Type nodeList_block = element[probRow].getVectorNodeList();
336 int dofs = std::get<2>(problemDisk->at(probRow));
337 int numNodes = std::get<3>(problemDisk->at(probRow));
338
339 int offset = numNodes*dofs;
340 for(int i=0; i< nodeList_block.size() ; i++){
341 for(int d=0; d<dofs; d++){
342 resArray_block[nodeList_block[i]*dofs+d] += (*rhsVec)[i*dofs+d+offset];
343 }
344 }
345 }
346}
347*/
348
351 \brief Assembly of Jacobian for Linear Elasticity
352@param[in] dim Dimension
353@param[in] FEType FE Discretization
354@param[in] degree Degree of basis function
355@param[in] A Resulting matrix
356@param[in] callFillComplete If Matrix A should be completely filled at end of function
357@param[in] FELocExternal
358
359*/
360
361template <class SC, class LO, class GO, class NO>
363 std::string FEType,
364 int degree,
365 int dofs,
366 MultiVectorPtr_Type d_rep,
367 BlockMatrixPtr_Type &A,
368 BlockMultiVectorPtr_Type &resVec,
369 ParameterListPtr_Type params,
370 bool reAssemble,
371 std::string assembleMode,
372 bool callFillComplete,
373 int FELocExternal){
374
375 ElementsPtr_Type elements = domainVec_.at(0)->getElementsC();
376
377 int dofsElement = elements->getElement(0).getVectorNodeList().size();
378
379 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(0)->getPointsRepeated();
380
381 MapConstPtr_Type mapVel = domainVec_.at(0)->getMapRepeated();
382
383 vec_dbl_Type solution(0);
384 vec_dbl_Type solution_d;
385
386 vec_dbl_Type rhsVec;
387
390 int numNodes=6;
391 if(dim==3){
392 numNodes=10;
393 }
394 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
395 tuple_ssii_Type displacement ("Displacement",FEType,dofs,numNodes);
396 problemDisk->push_back(displacement);
397
398 if(assemblyFEElements_.size()== 0)
399 initAssembleFEElements("LinearElasticity",problemDisk,elements, params,pointsRep,domainVec_.at(0)->getElementMap());
400 else if(assemblyFEElements_.size() != elements->numberElements())
401 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
402
403 MultiVectorPtr_Type resVec_d = Teuchos::rcp( new MultiVector_Type( domainVec_.at(0)->getMapVecFieldRepeated(), 1 ) );
404
405 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp( new BlockMultiVector_Type( 1) );
406 resVecRep->addBlock(resVec_d,0);
407
408 SmallMatrixPtr_Type elementMatrix;
409 for (UN T=0; T<assemblyFEElements_.size(); T++) {
410 vec_dbl_Type solution(0);
411
412 solution_d = getSolution(elements->getElement(T).getVectorNodeList(), d_rep,dofs);
413
414 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
415
416 assemblyFEElements_[T]->updateSolution(solution);
417
418 assemblyFEElements_[T]->assembleJacobian();
419
420 elementMatrix = assemblyFEElements_[T]->getJacobian();
421
422 assemblyFEElements_[T]->advanceNewtonStep();
423
424
425 addFeBlock(A, elementMatrix, elements->getElement(T), mapVel, 0, 0, problemDisk);
426
427 }
428 if (callFillComplete)
429 A->getBlock(0,0)->fillComplete( domainVec_.at(0)->getMapVecFieldUnique(),domainVec_.at(0)->getMapVecFieldUnique());
430
431
432
433
434}
435
448template <class SC, class LO, class GO, class NO>
450 std::string FEType,
451 int degree,
452 int dofs,
453 MultiVectorPtr_Type d_rep,
454 BlockMatrixPtr_Type &A,
455 BlockMultiVectorPtr_Type &resVec,
456 ParameterListPtr_Type params,
457 bool callFillComplete,
458 int FELocExternal){
459
460 ElementsPtr_Type elements = domainVec_.at(0)->getElementsC();
461
462 int dofsElement = elements->getElement(0).getVectorNodeList().size();
463
464 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(0)->getPointsRepeated();
465
466 MapConstPtr_Type map = domainVec_.at(0)->getMapRepeated();
467
468 vec_dbl_Type solution(0);
469 vec_dbl_Type solution_d;
470
471 vec_dbl_ptr_Type rhsVec;
472
475 int numNodes=6;
476 if(dim==3){
477 numNodes=10;
478 }
479 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
480 tuple_ssii_Type displacement ("Displacement",FEType,dofs,numNodes);
481 problemDisk->push_back(displacement);
482
483 int neoHookeNum = params->sublist("Parameter").get("Neo-Hooke Modell",1);
484
485 std::string nonLinElasModell = "NonLinearElasticity2";
486 if(neoHookeNum == 1)
487 nonLinElasModell = "NonLinearElasticity";
489 //std::cout << " ######## Assembly Modell: " << nonLinElasModell << " ############ " << std::endl;
490
491
492 if(assemblyFEElements_.size()== 0)
493 initAssembleFEElements(nonLinElasModell,problemDisk,elements, params,pointsRep,domainVec_.at(0)->getElementMap());
494 else if(assemblyFEElements_.size() != elements->numberElements())
495 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
497
498 SmallMatrixPtr_Type elementMatrix;
499 for (UN T=0; T<assemblyFEElements_.size(); T++) {
500 vec_dbl_Type solution(0);
501
502 solution_d = getSolution(elements->getElement(T).getVectorNodeList(), d_rep,dofs);
503
504 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
505
506 assemblyFEElements_[T]->updateSolution(solution);
507
508 assemblyFEElements_[T]->assembleJacobian();
509 elementMatrix = assemblyFEElements_[T]->getJacobian();
510 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0, problemDisk);
512 assemblyFEElements_[T]->assembleRHS();
513 rhsVec = assemblyFEElements_[T]->getRHS();
514 addFeBlockMv(resVec, rhsVec, elements->getElement(T), dofs);
515
516 assemblyFEElements_[T]->advanceNewtonStep();
517
518
519 }
520 if (callFillComplete)
521 A->getBlock(0,0)->fillComplete( domainVec_.at(0)->getMapVecFieldUnique(),domainVec_.at(0)->getMapVecFieldUnique());
522
523}
524
536
537template <class SC, class LO, class GO, class NO>
539 std::string FEType,
540 int degree,
541 int dofs,
542 MultiVectorPtr_Type d_rep,
543 BlockMatrixPtr_Type &A,
544 BlockMultiVectorPtr_Type &resVec,
545 ParameterListPtr_Type params,
546 DomainConstPtr_Type domain,
547 MultiVectorPtr_Type eModVec,
548 bool callFillComplete,
549 int FELocExternal){
550
551 ElementsPtr_Type elements = domain->getElementsC();
552
553 int dofsElement = elements->getElement(0).getVectorNodeList().size();
554
555 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
557 MapConstPtr_Type map = domain->getMapRepeated();
558
559 vec_dbl_Type solution(0);
560 vec_dbl_Type solution_d;
561
562 vec_dbl_ptr_Type rhsVec;
563
566 int numNodes=6;
567 if(dim==3){
568 numNodes=10;
570 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
571 tuple_ssii_Type displacement ("Displacement",FEType,dofs,numNodes);
572 problemDisk->push_back(displacement);
573
574 int neoHookeNum = params->sublist("Parameter").get("Neo-Hooke Modell",1);
575
576 std::string nonLinElasModell = "NonLinearElasticity2";
577 if(neoHookeNum == 1)
578 nonLinElasModell = "NonLinearElasticity";
579
580 //std::cout << " ######## Assembly Modell: " << nonLinElasModell << " ############ " << std::endl;
581
582 if(assemblyFEElements_.size()== 0)
583 initAssembleFEElements(nonLinElasModell,problemDisk,elements, params,pointsRep,domain->getElementMap());
584 else if(assemblyFEElements_.size() != elements->numberElements())
585 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
586
587 Teuchos::ArrayRCP<SC> eModVecA = eModVec->getDataNonConst(0);
588
589 SmallMatrixPtr_Type elementMatrix;
590 for (UN T=0; T<assemblyFEElements_.size(); T++) {
591 vec_dbl_Type solution(0);
592
593 solution_d = getSolution(elements->getElement(T).getVectorNodeList(), d_rep,dofs);
594
595 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
596
597 assemblyFEElements_[T]->updateSolution(solution);
598 assemblyFEElements_[T]->updateParameter("E",eModVecA[T]);
599 assemblyFEElements_[T]->assembleJacobian();
600 elementMatrix = assemblyFEElements_[T]->getJacobian();
601 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0, problemDisk);
602
603 assemblyFEElements_[T]->assembleRHS();
604 rhsVec = assemblyFEElements_[T]->getRHS();
605 addFeBlockMv(resVec, rhsVec, elements->getElement(T), dofs);
606
607 assemblyFEElements_[T]->advanceNewtonStep();
608
609
610 }
611 if (callFillComplete)
612 A->getBlock(0,0)->fillComplete( domainVec_.at(0)->getMapVecFieldUnique(),domainVec_.at(0)->getMapVecFieldUnique());
613
614}
615
616
617
628
629template <class SC, class LO, class GO, class NO>
630void FE<SC,LO,GO,NO>::addFeBlockMv(BlockMultiVectorPtr_Type &res, vec_dbl_ptr_Type rhsVec, FiniteElement elementBlock, int dofs){
631
632 Teuchos::ArrayRCP<SC> resArray_block = res->getBlockNonConst(0)->getDataNonConst(0);
633
634 vec_LO_Type nodeList_block = elementBlock.getVectorNodeList();
635
636 for(int i=0; i< nodeList_block.size() ; i++){
637 for(int d=0; d<dofs; d++)
638 resArray_block[nodeList_block[i]*dofs+d] += (*rhsVec)[i*dofs+d];
639 }
640}
641
642// Check the order of chemistry and solid in system matrix
643template <class SC, class LO, class GO, class NO>
645 std::string FETypeChem,
646 std::string FETypeSolid,
647 int degree,
648 int dofsChem,
649 int dofsSolid,
650 MultiVectorPtr_Type c_rep,
651 MultiVectorPtr_Type d_rep,
652 BlockMatrixPtr_Type &A,
653 BlockMultiVectorPtr_Type &resVec,
654 ParameterListPtr_Type params,
655 std::string assembleMode,
656 bool callFillComplete,
657 int FELocExternal){
658
659 if((FETypeChem != "P2") || (FETypeSolid != "P2") || dim != 3)
660 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "No AceGen Implementation available for Discretization and Dimension." );
661
662
663 UN FElocChem = 1; //checkFE(dim,FETypeChem); // Checks for different domains which belongs to a certain fetype
664 UN FElocSolid = 0; //checkFE(dim,FETypeSolid); // Checks for different domains which belongs to a certain fetype
665
666 ElementsPtr_Type elementsChem= domainVec_.at(FElocChem)->getElementsC();
667
668 ElementsPtr_Type elementsSolid = domainVec_.at(FElocSolid)->getElementsC();
669
670 //this->domainVec_.at(FElocChem)->info();
671 //this->domainVec_.at(FElocSolid)->info();
672 //int dofsElement = elements->getElement(0).getVectorNodeList().size();
673
674 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocSolid)->getPointsRepeated();
675
676 MapConstPtr_Type mapChem = domainVec_.at(FElocChem)->getMapRepeated();
677
678 MapConstPtr_Type mapSolid = domainVec_.at(FElocSolid)->getMapRepeated();
679
680 vec_dbl_Type solution_c;
681 vec_dbl_Type solution_d;
682
683 vec_dbl_ptr_Type rhsVec;
684
687 int numChem=3;
688 if(FETypeChem == "P2"){
689 numChem=6;
690 }
691 if(dim==3){
692 numChem=4;
693 if(FETypeChem == "P2")
694 numChem=10;
695 }
696 int numSolid=3;
697 if(FETypeSolid == "P2")
698 numSolid=6;
699
700 if(dim==3){
701 numSolid=4;
702 if(FETypeSolid == "P2")
703 numSolid=10;
704 }
705 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
706 tuple_ssii_Type chem ("Chemistry",FETypeChem,dofsChem,numChem);
707 tuple_ssii_Type solid ("Solid",FETypeSolid,dofsSolid,numSolid);
708 problemDisk->push_back(solid);
709 problemDisk->push_back(chem);
710
711 tuple_disk_vec_ptr_Type problemDiskChem = Teuchos::rcp(new tuple_disk_vec_Type(0));
712 problemDiskChem->push_back(chem);
713
714 std::string SCIModel = params->sublist("Parameter").get("Structure Model","SCI_simple");
715
716 if(assemblyFEElements_.size()== 0){
717 initAssembleFEElements(SCIModel,problemDisk,elementsChem, params,pointsRep,domainVec_.at(FElocSolid)->getElementMap());
718 }
719 else if(assemblyFEElements_.size() != elementsChem->numberElements())
720 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
721
722 //SmallMatrixPtr_Type elementMatrix =Teuchos::rcp( new SmallMatrix_Type( dofsElement));
723
724 MultiVectorPtr_Type resVec_c = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocChem)->getMapRepeated(), 1 ) );
725 MultiVectorPtr_Type resVec_d = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldRepeated(), 1 ) );
726
727 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp( new BlockMultiVector_Type( 2) );
728 resVecRep->addBlock(resVec_d,0);
729 resVecRep->addBlock(resVec_c,1);
730
731 SC detB;
732 SC absDetB;
733 SmallMatrix<SC> B(dim);
734 SmallMatrix<SC> Binv(dim);
735
736
737 for (UN T=0; T<assemblyFEElements_.size(); T++) {
738 vec_dbl_Type solution(0);
739
740 solution_c = getSolution(elementsChem->getElement(T).getVectorNodeList(), c_rep,dofsChem);
741 solution_d = getSolution(elementsSolid->getElement(T).getVectorNodeList(), d_rep,dofsSolid);
742
743 // First Solid, then Chemistry
744 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
745 solution.insert( solution.end(), solution_c.begin(), solution_c.end() );
746
747 assemblyFEElements_[T]->updateSolution(solution);
748
749 SmallMatrixPtr_Type elementMatrix;
750
751 // ------------------------
752 /*buildTransformation(elementsSolid->getElement(T).getVectorNodeList(), pointsRep, B, FETypeSolid);
753 detB = B.computeInverse(Binv);
754 absDetB = std::fabs(detB);
755 std::cout << " Determinante " << detB << std::endl;*/
756 // ------------------------
757
758
759
760
761 if(assembleMode == "Jacobian"){
762 assemblyFEElements_[T]->assembleJacobian();
763
764 elementMatrix = assemblyFEElements_[T]->getJacobian();
765 // elementMatrix->print();
766 assemblyFEElements_[T]->advanceNewtonStep(); // n genereal non linear solver step
767
768 addFeBlockMatrix(A, elementMatrix, elementsSolid->getElement(T), elementsSolid->getElement(T), mapSolid, mapChem, problemDisk);
769
770
771
772 }
773 if(assembleMode == "Rhs"){
774 assemblyFEElements_[T]->assembleRHS();
775 rhsVec = assemblyFEElements_[T]->getRHS();
776 addFeBlockMv(resVecRep, rhsVec, elementsSolid->getElement(T),elementsChem->getElement(T), dofsSolid,dofsChem);
777
778 }
779 if(assembleMode=="MassMatrix"){
780 assemblyFEElements_[T]->assembleJacobian();
781
782 AssembleFE_SCI_SMC_Active_Growth_Reorientation_Ptr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFE_SCI_SMC_Active_Growth_Reorientation_Type>(assemblyFEElements_[T] );
783 elTmp->getMassMatrix(elementMatrix);
784 //elementMatrix->print();
785 addFeBlock(A, elementMatrix, elementsChem->getElement(T), mapChem, 0, 0, problemDiskChem);
786
787
788 }
789
790
791
792
793 }
794 if ( assembleMode == "Jacobian"){
795 A->getBlock(0,0)->fillComplete();
796 A->getBlock(1,0)->fillComplete(domainVec_.at(FElocSolid)->getMapVecFieldUnique(),domainVec_.at(FElocChem)->getMapUnique());
797 A->getBlock(0,1)->fillComplete(domainVec_.at(FElocChem)->getMapUnique(),domainVec_.at(FElocSolid)->getMapVecFieldUnique());
798 A->getBlock(1,1)->fillComplete();
799 }
800 else if(assembleMode == "Rhs"){
801
802 MultiVectorPtr_Type resVecUnique_d = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldUnique(), 1 ) );
803 MultiVectorPtr_Type resVecUnique_c = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocChem)->getMapUnique(), 1 ) );
804
805 resVecUnique_d->putScalar(0.);
806 resVecUnique_c->putScalar(0.);
807
808 resVecUnique_d->exportFromVector( resVec_d, true, "Add" );
809 resVecUnique_c->exportFromVector( resVec_c, true, "Add" );
810
811 resVec->addBlock(resVecUnique_d,0);
812 resVec->addBlock(resVecUnique_c,1);
813 }
814 else if(assembleMode == "MassMatrix"){
815 A->getBlock(0,0)->fillComplete();
816 }
817
818}
819
820// Check the order of chemistry and solid in system matrix
821template <class SC, class LO, class GO, class NO>
823 std::string FETypeChem,
824 std::string FETypeSolid,
825 int degree,
826 int dofsChem,
827 int dofsSolid,
828 MultiVectorPtr_Type c_rep,
829 MultiVectorPtr_Type d_rep,
830 BlockMatrixPtr_Type &A,
831 int blockRow,
832 int blockCol,
833 BlockMultiVectorPtr_Type &resVec,
834 int block,
835 ParameterListPtr_Type params,
836 std::string assembleMode,
837 bool callFillComplete,
838 int FELocExternal){
839
840 if((FETypeChem != "P2") || (FETypeSolid != "P2") || dim != 3)
841 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "No AceGen Implementation available for Discretization and Dimension." );
842 if((blockRow != blockCol) && blockRow != 0)
843 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Block assemblyDeformDiffu AceGEN Version only implemented for 0,0 block right now" );
844
845 //UN FElocChem = 1; //checkFE(dim,FETypeChem); // Checks for different domains which belongs to a certain fetype
846 UN FElocSolid = 0; //checkFE(dim,FETypeSolid); // Checks for different domains which belongs to a certain fetype
847
848 ElementsPtr_Type elementsChem= domainVec_.at(FElocSolid)->getElementsC();
849
850 ElementsPtr_Type elementsSolid = domainVec_.at(FElocSolid)->getElementsC();
851
852 //this->domainVec_.at(FElocChem)->info();
853 //this->domainVec_.at(FElocSolid)->info();
854 //int dofsElement = elements->getElement(0).getVectorNodeList().size();
855
856 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocSolid)->getPointsRepeated();
857
858 //MapConstPtr_Type mapChem = domainVec_.at(FElocChem)->getMapRepeated();
859
860 MapConstPtr_Type mapSolid = domainVec_.at(FElocSolid)->getMapRepeated();
861
862 vec_dbl_Type solution_c;
863 vec_dbl_Type solution_d;
864
865 vec_dbl_ptr_Type rhsVec;
866
869 int numChem=3;
870 if(FETypeChem == "P2"){
871 numChem=6;
872 }
873 if(dim==3){
874 numChem=4;
875 if(FETypeChem == "P2")
876 numChem=10;
877 }
878 int numSolid=3;
879 if(FETypeSolid == "P2")
880 numSolid=6;
881
882 if(dim==3){
883 numSolid=4;
884 if(FETypeSolid == "P2")
885 numSolid=10;
886 }
887 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
888 tuple_ssii_Type chem ("Chemistry",FETypeChem,dofsChem,numChem);
889 tuple_ssii_Type solid ("Solid",FETypeSolid,dofsSolid,numSolid);
890 problemDisk->push_back(solid);
891 problemDisk->push_back(chem);
892
893 std::string SCIModel = params->sublist("Parameter").get("Structure Model","SCI_simple");
894
895 if(assemblyFEElements_.size()== 0){
896 initAssembleFEElements(SCIModel,problemDisk,elementsChem, params,pointsRep,domainVec_.at(FElocSolid)->getElementMap());
897 }
898 else if(assemblyFEElements_.size() != elementsChem->numberElements())
899 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
900
901 //SmallMatrixPtr_Type elementMatrix =Teuchos::rcp( new SmallMatrix_Type( dofsElement));
902
903 //MultiVectorPtr_Type resVec_c = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocChem)->getMapRepeated(), 1 ) );
904 MultiVectorPtr_Type resVec_d = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldRepeated(), 1 ) );
905
906 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp( new BlockMultiVector_Type( 1) );
907 resVecRep->addBlock(resVec_d,0);
908 //resVecRep->addBlock(resVec_c,1);
909
910 for (UN T=0; T<assemblyFEElements_.size(); T++) {
911 vec_dbl_Type solution(0);
912
913 solution_c = getSolution(elementsChem->getElement(T).getVectorNodeList(), c_rep,dofsChem);
914 solution_d = getSolution(elementsSolid->getElement(T).getVectorNodeList(), d_rep,dofsSolid);
915
916 // First Solid, then Chemistry
917 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
918 solution.insert( solution.end(), solution_c.begin(), solution_c.end() );
919
920 assemblyFEElements_[T]->updateSolution(solution);
921
922 SmallMatrixPtr_Type elementMatrix;
923
924 if(assembleMode == "Jacobian"){
925 assemblyFEElements_[T]->assembleJacobian();
926
927 elementMatrix = assemblyFEElements_[T]->getJacobian();
928 // elementMatrix->print();
929 assemblyFEElements_[T]->advanceNewtonStep(); // n genereal non linear solver step
930 addFeBlock(A, elementMatrix, elementsSolid->getElement(T), mapSolid, 0, 0, problemDisk);
931 //addFeBlockMatrix(A, elementMatrix, elementsSolid->getElement(T), mapSolid, mapChem, problemDisk);
932 }
933 if(assembleMode == "Rhs"){
934 assemblyFEElements_[T]->assembleRHS();
935 rhsVec = assemblyFEElements_[T]->getRHS();
936 addFeBlockMv(resVecRep, rhsVec, elementsSolid->getElement(T), dofsSolid);
937 }
938 //if(assembleMode=="compute")
939 // assemblyFEElements_[T]->compute();
940
941
942
943
944 }
945 if ( assembleMode != "Rhs"){
946 A->getBlock(0,0)->fillComplete();
947 //A->getBlock(1,0)->fillComplete(domainVec_.at(FElocSolid)->getMapVecFieldUnique(),domainVec_.at(FElocChem)->getMapUnique());
948 //A->getBlock(0,1)->fillComplete(domainVec_.at(FElocChem)->getMapUnique(),domainVec_.at(FElocSolid)->getMapVecFieldUnique());
949 //A->getBlock(1,1)->fillComplete();
950 }
951
952 if(assembleMode == "Rhs"){
953
954 MultiVectorPtr_Type resVecUnique_d = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldUnique(), 1 ) );
955 //MultiVectorPtr_Type resVecUnique_c = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocChem)->getMapUnique(), 1 ) );
956
957 resVecUnique_d->putScalar(0.);
958 //resVecUnique_c->putScalar(0.);
959
960 resVecUnique_d->exportFromVector( resVec_d, true, "Add" );
961 //resVecUnique_c->exportFromVector( resVec_c, true, "Add" );
962
963 resVec->addBlock(resVecUnique_d,0);
964 //resVec->addBlock(resVecUnique_c,1);
965 }
966
967
968}
969
981template <class SC, class LO, class GO, class NO>
982void FE<SC,LO,GO,NO>::addFeBlockMatrix(BlockMatrixPtr_Type &A, SmallMatrixPtr_Type elementMatrix, FiniteElement element1, FiniteElement element2, MapConstPtr_Type mapFirstRow,MapConstPtr_Type mapSecondRow, tuple_disk_vec_ptr_Type problemDisk){
983
984 int numDisk = problemDisk->size();
985
986 int dofs1 = std::get<2>(problemDisk->at(0));
987 int dofs2 = std::get<2>(problemDisk->at(1));
988
989 int numNodes1 = std::get<3>(problemDisk->at(0));
990 int numNodes2=std::get<3>(problemDisk->at(1));
991
992 int dofsBlock1 = dofs1*numNodes1;
993 int dofsBlock2 = dofs2*numNodes2;
994
995 Teuchos::Array<SC> value1( numNodes1, 0. );
996 Teuchos::Array<GO> columnIndices1( numNodes1, 0 );
997
998 Teuchos::Array<SC> value2( numNodes2, 0. );
999 Teuchos::Array<GO> columnIndices2( numNodes2, 0 );
1000
1001 for (UN i=0; i < numNodes1 ; i++) {
1002 for(int di=0; di<dofs1; di++){
1003 GO row =GO (dofs1* mapFirstRow->getGlobalElement( element1.getNode(i) )+di);
1004 for(int d=0; d<dofs1; d++){
1005 for (UN j=0; j < columnIndices1.size(); j++){
1006 columnIndices1[j] = GO ( dofs1 * mapFirstRow->getGlobalElement( element1.getNode(j) ) + d );
1007 value1[j] = (*elementMatrix)[dofs1*i+di][dofs1*j+d];
1008 }
1009 A->getBlock(0,0)->insertGlobalValues( row, columnIndices1(), value1() ); // Automatically adds entries if a value already exists
1010 }
1011 }
1012 }
1013 int offset= numNodes1*dofs1;
1014
1015
1016 Teuchos::Array<SC> value( 1, 0. );
1017 Teuchos::Array<GO> columnIndex( 1, 0 );
1018 for (UN i=0; i < numNodes2 ; i++) {
1019 for(int di=0; di<dofs2; di++){
1020 GO row =GO (dofs2* mapSecondRow->getGlobalElement( element2.getNode(i) )+di);
1021 for(int d=0; d<dofs2; d++){
1022 for (UN j=0; j < columnIndices2.size(); j++){
1023 double tmpValue = (*elementMatrix)[offset+dofs2*i+di][offset+dofs2*j+d];
1024 if(std::fabs(tmpValue) > 1.e-13){
1025 columnIndex[0] = GO ( dofs2 * mapSecondRow->getGlobalElement( element2.getNode(j) ) + d );
1026 value[0] = tmpValue;
1027 A->getBlock(1,1)->insertGlobalValues( row, columnIndex(), value() ); // Automatically adds entries if a value already exists
1028
1029 }
1030 }
1031 }
1032 }
1033 }
1034
1035 for (UN i=0; i < numNodes1; i++){
1036 for(int di=0; di<dofs1; di++){
1037 GO row =GO (dofs1* mapFirstRow->getGlobalElement( element1.getNode(i) )+di);
1038 for(int d=0; d<dofs2; d++){
1039 for (UN j=0; j < numNodes2 ; j++) {
1040 value2[j] = (*elementMatrix)[i*dofs1+di][offset+j*dofs2+d];
1041 columnIndices2[j] =GO (dofs2* mapSecondRow->getGlobalElement( element2.getNode(j) )+d);
1042 }
1043 A->getBlock(0,1)->insertGlobalValues( row, columnIndices2(), value2() ); // Automatically adds entries if a value already exists
1044 }
1045 }
1046 }
1047
1048 for (UN j=0; j < numNodes2; j++){
1049 for(int di=0; di<dofs2; di++){
1050 GO row = GO (dofs2* mapSecondRow->getGlobalElement( element2.getNode(j) ) +di );
1051 for(int d=0; d<dofs1; d++){
1052 for (UN i=0; i < numNodes1 ; i++) {
1053 value1[i] = (*elementMatrix)[offset+j*dofs2+di][dofs1*i+d];
1054 columnIndices1[i] =GO (dofs1* mapFirstRow->getGlobalElement( element1.getNode(i) )+d);
1055 }
1056 A->getBlock(1,0)->insertGlobalValues( row, columnIndices1(), value1() ); // Automatically adds entries if a value already exists
1057 }
1058 }
1059 }
1060
1061
1062}
1063
1064
1076
1077template <class SC, class LO, class GO, class NO>
1079 std::string FETypeVelocity,
1080 std::string FETypePressure,
1081 int degree,
1082 int dofsVelocity,
1083 int dofsPressure,
1084 MultiVectorPtr_Type u_rep,
1085 MultiVectorPtr_Type p_rep,
1086 BlockMatrixPtr_Type &A,
1087 BlockMultiVectorPtr_Type &resVec,
1088 SmallMatrix_Type coeff,
1089 ParameterListPtr_Type params,
1090 bool reAssemble,
1091 std::string assembleMode,
1092 bool callFillComplete,
1093 int FELocExternal){
1094
1095
1096 UN FElocVel = checkFE(dim,FETypeVelocity); // Checks for different domains which belongs to a certain fetype
1097 UN FElocPres = checkFE(dim,FETypePressure); // Checks for different domains which belongs to a certain fetype
1098
1099 ElementsPtr_Type elements = domainVec_.at(FElocVel)->getElementsC();
1100
1101 ElementsPtr_Type elementsPres = domainVec_.at(FElocPres)->getElementsC();
1102
1103 int dofsElement = elements->getElement(0).getVectorNodeList().size();
1104
1105 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocVel)->getPointsRepeated();
1106
1107 MapConstPtr_Type mapVel = domainVec_.at(FElocVel)->getMapRepeated();
1108
1109 MapConstPtr_Type mapPres = domainVec_.at(FElocPres)->getMapRepeated();
1110
1111 vec_dbl_Type solution(0);
1112 vec_dbl_Type solution_u;
1113 vec_dbl_Type solution_p;
1114
1115 vec_dbl_ptr_Type rhsVec;
1116
1119 int numVelo=3;
1120 if(FETypeVelocity == "P2")
1121 numVelo=6;
1122
1123 if(dim==3){
1124 numVelo=4;
1125 if(FETypeVelocity == "P2")
1126 numVelo=10;
1127 }
1128 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
1129 tuple_ssii_Type vel ("Velocity",FETypeVelocity,dofsVelocity,numVelo);
1130 tuple_ssii_Type pres ("Pressure",FETypePressure,dofsPressure,dim+1);
1131 problemDisk->push_back(vel);
1132 problemDisk->push_back(pres);
1133
1134 if(assemblyFEElements_.size()== 0){
1135 if(params->sublist("Material").get("Newtonian",true) == false)
1136 initAssembleFEElements("GeneralizedNewtonian",problemDisk,elements, params,pointsRep,domainVec_.at(FElocVel)->getElementMap()); // In cas of non Newtonian Fluid
1137 else
1138 initAssembleFEElements("NavierStokes",problemDisk,elements, params,pointsRep,domainVec_.at(FElocVel)->getElementMap());
1139 }
1140 else if(assemblyFEElements_.size() != elements->numberElements())
1141 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
1142
1143 //SmallMatrixPtr_Type elementMatrix =Teuchos::rcp( new SmallMatrix_Type( dofsElement));
1144
1145 MultiVectorPtr_Type resVec_u = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocVel)->getMapVecFieldRepeated(), 1 ) );
1146 MultiVectorPtr_Type resVec_p = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocPres)->getMapRepeated(), 1 ) );
1147
1148 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp( new BlockMultiVector_Type( 2) );
1149 resVecRep->addBlock(resVec_u,0);
1150 resVecRep->addBlock(resVec_p,1);
1151
1152
1153 for (UN T=0; T<assemblyFEElements_.size(); T++) {
1154 vec_dbl_Type solution(0);
1155
1156 solution_u = getSolution(elements->getElement(T).getVectorNodeList(), u_rep,dofsVelocity);
1157 solution_p = getSolution(elementsPres->getElement(T).getVectorNodeList(), p_rep,dofsPressure);
1158
1159 solution.insert( solution.end(), solution_u.begin(), solution_u.end() );
1160 solution.insert( solution.end(), solution_p.begin(), solution_p.end() );
1161
1162 assemblyFEElements_[T]->updateSolution(solution);
1163
1164 SmallMatrixPtr_Type elementMatrix;
1165
1166 if(assembleMode == "Jacobian"){
1167 assemblyFEElements_[T]->assembleJacobian();
1168
1169 elementMatrix = assemblyFEElements_[T]->getJacobian();
1170
1171 assemblyFEElements_[T]->advanceNewtonStep(); // n genereal non linear solver step
1172
1173 if(reAssemble)
1174 addFeBlock(A, elementMatrix, elements->getElement(T), mapVel, 0, 0, problemDisk);
1175 else
1176 addFeBlockMatrix(A, elementMatrix, elements->getElement(T), elementsPres->getElement(T), mapVel, mapPres, problemDisk);
1177 }
1178 if(assembleMode == "FixedPoint"){
1179
1180 //AssembleFENavierStokesPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFENavierStokes_Type>(assemblyFEElements_[T] ); // Why should we need a pointer we can directly call it using assemblyFEElements_[T]? Because assemblyFixedPoint is not a function of base class
1181
1182 if(params->sublist("Material").get("Newtonian",true) == false)
1183 {
1184 AssembleFEGeneralizedNewtonianPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFEGeneralizedNewtonian_Type>( assemblyFEElements_[T] );
1185 elTmp->assembleFixedPoint();
1186 elementMatrix = elTmp->getFixedPointMatrix();
1187 }
1188 else // Newtonian Case
1189 {
1190 AssembleFENavierStokesPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFENavierStokes_Type>( assemblyFEElements_[T] );
1191 elTmp->assembleFixedPoint();
1192 elementMatrix = elTmp->getFixedPointMatrix();
1193 }
1194
1195
1196 assemblyFEElements_[T]->advanceNewtonStep(); // n genereal non linear solver step
1197
1198 if(reAssemble)
1199 addFeBlock(A, elementMatrix, elements->getElement(T), mapVel, 0, 0, problemDisk);
1200 else
1201 addFeBlockMatrix(A, elementMatrix, elements->getElement(T), elementsPres->getElement(T),mapVel, mapPres, problemDisk);
1202
1203 }
1204 if(assembleMode == "Rhs"){
1205 AssembleFENavierStokesPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFENavierStokes_Type>(assemblyFEElements_[T] );
1206 elTmp->setCoeff(coeff);// Coeffs from time discretization. Right now default [1][1] // [0][0]
1207 assemblyFEElements_[T]->assembleRHS();
1208 rhsVec = assemblyFEElements_[T]->getRHS();
1209 addFeBlockMv(resVecRep, rhsVec, elements->getElement(T),elementsPres->getElement(T), dofsVelocity,dofsPressure);
1210 }
1211
1212
1213 }
1214 if (callFillComplete && reAssemble && assembleMode != "Rhs" )
1215 A->getBlock(0,0)->fillComplete( domainVec_.at(FElocVel)->getMapVecFieldUnique(),domainVec_.at(FElocVel)->getMapVecFieldUnique());
1216 else if(callFillComplete && !reAssemble && assembleMode != "Rhs"){
1217 A->getBlock(0,0)->fillComplete();
1218 A->getBlock(1,0)->fillComplete(domainVec_.at(FElocVel)->getMapVecFieldUnique(),domainVec_.at(FElocPres)->getMapUnique());
1219 A->getBlock(0,1)->fillComplete(domainVec_.at(FElocPres)->getMapUnique(),domainVec_.at(FElocVel)->getMapVecFieldUnique());
1220 A->getBlock(1,1)->fillComplete();
1221 }
1222
1223 if(assembleMode == "Rhs"){
1224
1225 MultiVectorPtr_Type resVecUnique_u = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocVel)->getMapVecFieldUnique(), 1 ) );
1226 MultiVectorPtr_Type resVecUnique_p = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocPres)->getMapUnique(), 1 ) );
1227
1228 resVecUnique_u->putScalar(0.);
1229 resVecUnique_p->putScalar(0.);
1230
1231 resVecUnique_u->exportFromVector( resVec_u, true, "Add" );
1232 resVecUnique_p->exportFromVector( resVec_p, true, "Add" );
1233
1234 resVec->addBlock(resVecUnique_u,0);
1235 resVec->addBlock(resVecUnique_p,1);
1236 }
1237
1238
1239}
1240
1241
1250
1251
1252template <class SC, class LO, class GO, class NO>
1254 std::string FETypeVelocity,
1255 std::string FETypePressure,
1256 int dofsVelocity,
1257 int dofsPressure,
1258 MultiVectorPtr_Type u_rep,
1259 MultiVectorPtr_Type p_rep,
1260 ParameterListPtr_Type params){
1261
1262
1263 UN FElocVel = checkFE(dim,FETypeVelocity); // Checks for different domains which belongs to a certain fetype
1264 UN FElocPres = checkFE(dim,FETypePressure); // Checks for different domains which belongs to a certain fetype
1265
1266 ElementsPtr_Type elements = domainVec_.at(FElocVel)->getElementsC();
1267 ElementsPtr_Type elementsPres = domainVec_.at(FElocPres)->getElementsC();
1268
1269 vec_dbl_Type solution(0);
1270 vec_dbl_Type solution_u;
1271 vec_dbl_Type solution_p;
1272 vec_dbl_Type solution_viscosity;
1273
1274 // We have to compute viscosity solution in each element
1275 MultiVectorPtr_Type Sol_viscosity = Teuchos::rcp( new MultiVector_Type( domainVec_.at(FElocVel)->getElementMap(), 1 ) ); //
1276 BlockMultiVectorPtr_Type visco_output = Teuchos::rcp( new BlockMultiVector_Type(1) );
1277 visco_output->addBlock(Sol_viscosity,0);
1278
1279
1280 for (UN T=0; T<assemblyFEElements_.size(); T++) {
1281
1282 vec_dbl_Type solution(0);
1283 solution_u = getSolution(elements->getElement(T).getVectorNodeList(), u_rep,dofsVelocity); // get the solution inside an element on the nodes
1284 solution_p = getSolution(elementsPres->getElement(T).getVectorNodeList(), p_rep,dofsPressure);
1285
1286 solution.insert( solution.end(), solution_u.begin(), solution_u.end() ); // here we insert the solution
1287 solution.insert( solution.end(), solution_p.begin(), solution_p.end() );
1288
1289 assemblyFEElements_[T]->updateSolution(solution); // here we update the value of the solutions inside an element
1290
1291 assemblyFEElements_[T]->computeLocalconstOutputField(); // we compute the viscosity inside an element
1292 solution_viscosity = assemblyFEElements_[T]->getLocalconstOutputField();
1293
1294 Teuchos::ArrayRCP<SC> resArray_block = visco_output->getBlockNonConst(0)->getDataNonConst(0); // First
1295 resArray_block[T] = solution_viscosity[0]; // although it is a vector it only has one entry because we compute the value in the center of the element
1296
1297 } // end loop over all elements
1298 // We could also instead of just overwrite it add an aditional block such that we could also compute other output fields and save it in there
1299 this->const_output_fields= visco_output;
1300
1301
1302}
1303
1304
1305
1316
1317template <class SC, class LO, class GO, class NO>
1318void FE<SC,LO,GO,NO>::addFeBlockMv(BlockMultiVectorPtr_Type &res, vec_dbl_ptr_Type rhsVec, FiniteElement elementBlock1,FiniteElement elementBlock2, int dofs1, int dofs2 ){
1319
1320 Teuchos::ArrayRCP<SC> resArray_block1 = res->getBlockNonConst(0)->getDataNonConst(0);
1321
1322 Teuchos::ArrayRCP<SC> resArray_block2 = res->getBlockNonConst(1)->getDataNonConst(0);
1323
1324 vec_LO_Type nodeList_block1 = elementBlock1.getVectorNodeList();
1325
1326 vec_LO_Type nodeList_block2 = elementBlock2.getVectorNodeList();
1327
1328 for(int i=0; i< nodeList_block1.size() ; i++){
1329 for(int d=0; d<dofs1; d++){
1330 resArray_block1[nodeList_block1[i]*dofs1+d] += (*rhsVec)[i*dofs1+d];
1331 }
1332 }
1333 int offset = nodeList_block1.size()*dofs1;
1334
1335 for(int i=0; i < nodeList_block2.size(); i++){
1336 for(int d=0; d<dofs2; d++)
1337 resArray_block2[nodeList_block2[i]*dofs2+d] += (*rhsVec)[i*dofs2+d+offset];
1338 }
1339
1340}
1341
1342
1355template <class SC, class LO, class GO, class NO>
1356void FE<SC,LO,GO,NO>::addFeBlock(BlockMatrixPtr_Type &A, SmallMatrixPtr_Type elementMatrix, FiniteElement element, MapConstPtr_Type mapRow, int row, int column, tuple_disk_vec_ptr_Type problemDisk){
1357
1358 int dofs1 = std::get<2>(problemDisk->at(row));
1359
1360 int numNodes1 = std::get<3>(problemDisk->at(row));
1361
1362 int dofsBlock1 = dofs1*numNodes1;
1363
1364 Teuchos::Array<SC> value( numNodes1, 0. );
1365 Teuchos::Array<GO> columnIndices( numNodes1, 0 );
1366
1367 for (UN i=0; i < numNodes1 ; i++) {
1368 for(int di=0; di<dofs1; di++){
1369 GO rowID =GO (dofs1* mapRow->getGlobalElement( element.getNode(i) )+di);
1370 for(int d=0; d<dofs1; d++){
1371 for (UN j=0; j < columnIndices.size(); j++){
1372 columnIndices[j] = GO ( dofs1 * mapRow->getGlobalElement( element.getNode(j) ) + d );
1373 value[j] = (*elementMatrix)[dofs1*i+di][dofs1*j+d];
1374 }
1375 A->getBlock(row,column)->insertGlobalValues( rowID, columnIndices(), value() ); // Automatically adds entries if a value already exists
1376 }
1377 }
1378 }
1379}
1380
1391template <class SC, class LO, class GO, class NO>
1392void FE<SC,LO,GO,NO>::initAssembleFEElements(std::string elementType,tuple_disk_vec_ptr_Type problemDisk,ElementsPtr_Type elements, ParameterListPtr_Type params,vec2D_dbl_ptr_Type pointsRep, MapConstPtr_Type elementMap){
1393
1394 vec2D_dbl_Type nodes;
1395 for (UN T=0; T<elements->numberElements(); T++) {
1396
1397 nodes = getCoordinates(elements->getElement(T).getVectorNodeList(), pointsRep);
1398
1399 AssembleFEFactory<SC,LO,GO,NO> assembleFEFactory;
1400
1401 AssembleFEPtr_Type assemblyFE = assembleFEFactory.build(elementType,elements->getElement(T).getFlag(),nodes, params,problemDisk);
1402 //
1403 assemblyFE->setGlobalElementID(elementMap->getGlobalElement(T));
1404
1405 assemblyFEElements_.push_back(assemblyFE);
1406
1407 }
1408
1409}
1410
1420
1421template <class SC, class LO, class GO, class NO>
1422vec2D_dbl_Type FE<SC,LO,GO,NO>::getCoordinates(vec_LO_Type localIDs, vec2D_dbl_ptr_Type points){
1423
1424 vec2D_dbl_Type coordinates(0,vec_dbl_Type( points->at(0).size()));
1425 for(int i=0; i < localIDs.size() ; i++){
1426 coordinates.push_back(points->at(localIDs[i]));
1427 }
1428
1429 return coordinates;
1430}
1431
1441
1442template <class SC, class LO, class GO, class NO>
1443vec_dbl_Type FE<SC,LO,GO,NO>::getSolution(vec_LO_Type localIDs, MultiVectorPtr_Type u_rep, int dofsVelocity){
1444
1445 Teuchos::ArrayRCP<SC> uArray = u_rep->getDataNonConst(0);
1446
1447 vec_dbl_Type solution(0);
1448 for(int i=0; i < localIDs.size() ; i++){
1449 for(int d=0; d<dofsVelocity; d++)
1450 solution.push_back(uArray[localIDs[i]*dofsVelocity+d]);
1451 }
1452
1453 return solution;
1454}
1455
1456
1457template <class SC, class LO, class GO, class NO>
1458void FE<SC,LO,GO,NO>::applyBTinv( vec3D_dbl_ptr_Type& dPhiIn,
1459 vec3D_dbl_Type& dPhiOut,
1460 const SmallMatrix<SC>& Binv){
1461 UN dim = Binv.size();
1462 for (UN w=0; w<dPhiIn->size(); w++){
1463 for (UN i=0; i < dPhiIn->at(w).size(); i++) {
1464 for (UN d1=0; d1<dim; d1++) {
1465 for (UN d2=0; d2<dim; d2++) {
1466 dPhiOut[w][i][d1] += dPhiIn->at(w).at(i).at(d2) * Binv[d2][d1];
1467 }
1468 }
1469 }
1470 }
1471}
1472
1473template <class SC, class LO, class GO, class NO>
1474void FE<SC,LO,GO,NO>::assemblyEmptyMatrix(MatrixPtr_Type &A){
1475 A->fillComplete();
1476}
1477template <class SC, class LO, class GO, class NO>
1478void FE<SC,LO,GO,NO>::assemblyIdentity(MatrixPtr_Type &A){
1479 Teuchos::Array<SC> value(1, Teuchos::ScalarTraits<SC>::one() );
1480 Teuchos::Array<GO> index(1);
1481 MapConstPtr_Type map = A->getMap();
1482 for (int i=0; i<A->getNodeNumRows(); i++) {
1483 index[0] = map->getGlobalElement( i );
1484 A->insertGlobalValues( index[0], index(), value() );
1485 }
1486 A->fillComplete();
1487}
1488
1489// Assembling the nonlinear reaction part of Reaction-Diffusion equation
1490// Gerneral function in case of nonlinear reaction function
1491// template <class SC, class LO, class GO, class NO>
1492// void FE<SC,LO,GO,NO>::assemblyReactionTerm(int dim,
1493// std::string FEType,
1494// MatrixPtr_Type &A,
1495// MultiVectorPtr_Type u,
1496// bool callFillComplete,
1497// std::vector<SC>& funcParameter,
1498// RhsFunc_Type reactionFunc){
1499
1500// //TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
1501// TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
1502
1503// UN FEloc = checkFE(dim,FEType);
1504
1505// ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1506
1507// vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1508
1509// MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1510
1511// vec2D_dbl_ptr_Type phi;
1512// vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
1513
1514// // TODO: [JK] 2025/04 What is the getting integrated; i.e., what motivates the choice of polynomial degree?
1515
1516// UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv0); //Elementwise assembly of grad u
1517// UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv1) +
1518// Helper::determineDegree( dim, FEType, Helper::Deriv0) +
1519// extraDeg;
1520
1521// Helper::getPhi(phi, weights, dim, FEType, deg);
1522
1523// // We have a scalar value of concentration in each point
1524// vec_dbl_Type uLoc( weights->size() , -1. );
1525// Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
1526
1527// std::vector<double> valueFunc(1);
1528
1529// SC* paras = &(funcParameter[0]);
1530
1531// SC detB;
1532// SC absDetB;
1533// SmallMatrix<SC> B(dim);
1534// SmallMatrix<SC> Binv(dim);
1535
1536// for (UN T=0; T<elements->numberElements(); T++) {
1537// Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
1538// detB = B.computeInverse(Binv);
1539// absDetB = std::fabs(detB);
1540
1541// // Building u
1542// for (int w=0; w<phi->size(); w++){ //quadpoints
1543// uLoc[w] = 0.;
1544// for (int i=0; i < phi->at(0).size(); i++) { // points of element
1545// LO index = elements->getElement(T).getNode(i);
1546// uLoc[w] += uArray[index] * phi->at(w).at(i);
1547// }
1548// }
1549
1550// for (UN i=0; i < phi->at(0).size(); i++) {
1551// Teuchos::Array<SC> value( phi->at(0).size(), 0. );
1552// Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
1553// for (UN j=0; j < value.size(); j++) {
1554// for (UN w=0; w<phi->size(); w++) {
1555// value[j] += weights->at(w) * uLoc[w] * (*phi)[w][i] ;
1556// }
1557// reactionFunc(&value[j], &valueFunc[0] ,paras);
1558
1559// value[j] *= valueFunc[0] * absDetB;
1560// if (setZeros_ && std::fabs(value[j]) < myeps_) {
1561// value[j] = 0.;
1562// }
1563// indices[j] = GO( map->getGlobalElement( elements->getElement(T).getNode(j) ));
1564
1565// }
1566// GO row = GO ( map->getGlobalElement( elements->getElement(T).getNode(i) ) );
1567
1568
1569// A->insertGlobalValues( row, indices(), value() );
1570
1571// }
1572// }
1573
1574// if (callFillComplete)
1575// A->fillComplete();
1576// }
1577
1578
1579// // Assembling the nonlinear reaction part of Reaction-Diffusion equation
1580// template <class SC, class LO, class GO, class NO>
1581// void FE<SC,LO,GO,NO>::assemblyLinearReactionTerm(int dim,
1582// std::string FEType,
1583// MatrixPtr_Type &A,
1584// bool callFillComplete,
1585// std::vector<SC>& funcParameter,
1586// RhsFunc_Type reactionFunc){
1587
1588// //TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
1589// TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
1590
1591// UN FEloc = checkFE(dim,FEType);
1592
1593// ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1594
1595// vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1596
1597// MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1598
1599// vec2D_dbl_ptr_Type phi;
1600// vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
1601
1602// // TODO: [JK] 2025/04 What is the getting integrated; i.e., what motivates the choice of polynomial degree?
1603// UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv0); //Elementwise assembly of grad u
1604// UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv1) +
1605// Helper::determineDegree( dim, FEType, Helper::Deriv0) +
1606// extraDeg;
1607
1608// Helper::getPhi(phi, weights, dim, FEType, deg);
1609
1610// std::vector<double> valueFunc(1);
1611
1612// SC* paras = &(funcParameter[0]);
1613
1614// SC detB;
1615// SC absDetB;
1616// SmallMatrix<SC> B(dim);
1617// SmallMatrix<SC> Binv(dim);
1618
1619// for (UN T=0; T<elements->numberElements(); T++) {
1620// Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
1621// detB = B.computeInverse(Binv);
1622// absDetB = std::fabs(detB);
1623
1624// for (UN i=0; i < phi->at(0).size(); i++) {
1625// Teuchos::Array<SC> value( phi->at(0).size(), 0. );
1626// Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
1627// for (UN j=0; j < value.size(); j++) {
1628// for (UN w=0; w<phi->size(); w++) {
1629// value[j] += weights->at(w) * (*phi)[w][j] * (*phi)[w][i] ;
1630// }
1631// reactionFunc(&value[j], &valueFunc[0] ,paras);
1632
1633// value[j] *= valueFunc[0] * absDetB;
1634// if (setZeros_ && std::fabs(value[j]) < myeps_) {
1635// value[j] = 0.;
1636// }
1637// indices[j] = GO( map->getGlobalElement( elements->getElement(T).getNode(j) ));
1638
1639// }
1640// GO row = GO ( map->getGlobalElement( elements->getElement(T).getNode(i) ) );
1641
1642// A->insertGlobalValues( row, indices(), value() );
1643
1644// }
1645// }
1646// if (callFillComplete)
1647// A->fillComplete();
1648
1649// A->print();
1650
1651// }
1652
1653// Assembling the nonlinear reaction part of Reaction-Diffusion equation
1654// template <class SC, class LO, class GO, class NO>
1655// void FE<SC,LO,GO,NO>::assemblyDReactionTerm(int dim,
1656// std::string FEType,
1657// MatrixPtr_Type &A,
1658// MultiVectorPtr_Type u,
1659// bool callFillComplete,
1660// std::vector<SC>& funcParameter,
1661// RhsFunc_Type reactionFunc){
1662
1663// //TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
1664// TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
1665
1666// UN FEloc = checkFE(dim,FEType);
1667
1668// ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1669
1670// vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1671
1672// MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1673
1674// vec2D_dbl_ptr_Type phi;
1675// vec3D_dbl_ptr_Type dPhi;
1676// vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
1677
1678// // TODO: [JK] 2025/04 What is the getting integrated; i.e., what motivates the choice of polynomial degree?
1679// UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv0); //Elementwise assembly of grad u
1680// UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv1) +
1681// Helper::determineDegree( dim, FEType, Helper::Deriv0) +
1682// extraDeg;
1683
1684// Helper::getPhi(phi, weights, dim, FEType, deg);
1685
1686// Helper::getDPhi(dPhi, weights, dim, FEType, deg);
1687
1688// // We have a scalar value of concentration in each point
1689// vec2D_dbl_Type duLoc( weights->size() ,vec_dbl_Type(dim ,-1. ));
1690// Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
1691
1692// std::vector<double> valueFunc(1);
1693
1694// SC* paras = &(funcParameter[0]);
1695
1696// SC detB;
1697// SC absDetB;
1698// SmallMatrix<SC> B(dim);
1699// SmallMatrix<SC> Binv(dim);
1700
1701// for (UN T=0; T<elements->numberElements(); T++) {
1702
1703
1704// Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
1705// detB = B.computeInverse(Binv);
1706// absDetB = std::fabs(detB);
1707
1708// vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
1709// applyBTinv( dPhi, dPhiTrans, Binv );
1710
1711// for (int w=0; w<dPhiTrans.size(); w++){ //quads points
1712// for (int i=0; i < dPhiTrans[0].size(); i++) {
1713// LO index = elements->getElement(T).getNode(i) ;
1714// for (int d2=0; d2<dim; d2++)
1715// duLoc[w][d2] += uArray[index] * dPhiTrans[w][i][d2];
1716// }
1717
1718// }
1719
1720
1721// for (UN i=0; i < phi->at(0).size(); i++) {
1722// Teuchos::Array<SC> value( phi->at(0).size(), 0. );
1723// Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
1724// for (UN j=0; j < value.size(); j++) {
1725// for (UN d2=0; d2<dim; d2++){
1726// for (UN w=0; w<phi->size(); w++) {
1727// value[j] += weights->at(w) * duLoc[w][d2] * (*phi)[w][i] ;
1728// }
1729// }
1730// reactionFunc(&value[j], &valueFunc[0] ,paras);
1731
1732// value[j] *= valueFunc[0] * absDetB;
1733// if (setZeros_ && std::fabs(value[j]) < myeps_) {
1734// value[j] = 0.;
1735// }
1736// indices[j] = GO( map->getGlobalElement( elements->getElement(T).getNode(j) ));
1737
1738// }
1739// GO row = GO ( map->getGlobalElement( elements->getElement(T).getNode(i) ) );
1740// A->insertGlobalValues( row, indices(), value() );
1741// }
1742// }
1743
1744// if (callFillComplete)
1745// A->fillComplete();
1746// }
1747
1757template <class SC, class LO, class GO, class NO>
1759 std::string FEType,
1760 int degree,
1761 int dofs,
1762 BlockMatrixPtr_Type &A,
1763 bool callFillComplete,
1764 int FELocExternal){
1765 ParameterListPtr_Type params = Teuchos::getParametersFromXmlFile("parametersProblemLaplace.xml");
1766
1767 UN FEloc = checkFE(dim,FEType);
1768 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1769 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1770 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1771 vec2D_dbl_Type nodes;
1772 int numNodes=dim+1;
1773 if(FEType == "P2"){
1774 numNodes= 6;
1775 if(dim==3)
1776 numNodes=10;
1777 }
1778 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(new tuple_disk_vec_Type(0));
1779 tuple_ssii_Type vel ("Laplace",FEType,dofs,numNodes);
1780 problemDisk->push_back(vel);
1781 if(assemblyFEElements_.size()== 0)
1782 initAssembleFEElements("Laplace",problemDisk,elements, params,pointsRep,domainVec_.at(0)->getElementMap());
1783 else if(assemblyFEElements_.size() != elements->numberElements())
1784 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Number Elements not the same as number assembleFE elements." );
1785 for (UN T=0; T<elements->numberElements(); T++) {
1786 assemblyFEElements_[T]->assembleJacobian();
1787 SmallMatrixPtr_Type elementMatrix = assemblyFEElements_[T]->getJacobian();
1788 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0, problemDisk);
1789
1790 }
1791 if(callFillComplete)
1792 A->getBlock(0,0)->fillComplete();
1793}
1794
1795
1796template <class SC, class LO, class GO, class NO>
1797void FE<SC,LO,GO,NO>::assemblyLaplaceDiffusion(int dim,
1798 std::string FEType,
1799 int degree,
1800 MatrixPtr_Type &A,
1801 vec2D_dbl_Type diffusionTensor,
1802 bool callFillComplete,
1803 int FELocExternal){
1804 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
1805 UN FEloc;
1806 if (FELocExternal<0)
1807 FEloc = checkFE(dim,FEType);
1808 else
1809 FEloc = FELocExternal;
1810
1811 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1812
1813 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1814
1815 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1816
1817 vec3D_dbl_ptr_Type dPhi;
1818 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
1819
1820 // inner( grad(u) , grad(v) ) has twice the polyonimial degree than grad(u) or grad(v).
1821 // The diffusion tensor is constant and, thus, does not require a higher-order quadrature rule.
1822 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);//+1;
1823 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
1824
1825 SC detB;
1826 SC absDetB;
1827 SmallMatrix<SC> B(dim);
1828 SmallMatrix<SC> Binv(dim);
1829 GO glob_i, glob_j;
1830 vec_dbl_Type v_i(dim);
1831 vec_dbl_Type v_j(dim);
1832
1833
1834 SmallMatrix<SC> diffusionT(dim);
1835 // Linear Diffusion Tensor
1836 if(diffusionTensor.size()==0 || diffusionTensor.size() < dim ){
1837 vec2D_dbl_Type diffusionTensor(3,vec_dbl_Type(3,0));
1838 for(int i=0; i< dim; i++){
1839 diffusionTensor[i][i]=1.;
1840 }
1841 }
1842
1843 for(int i=0; i< dim; i++){
1844 for(int j=0; j<dim; j++){
1845 diffusionT[i][j]=diffusionTensor[i][j];
1846 }
1847 }
1848 //Teuchos::ArrayRCP< SC > linearDiff = diffusionTensor->getDataNonConst( 0 );
1849 //std::cout << "Assembly Info " << "num Elements " << elements->numberElements() << " num Nodes " << pointsRep->size() << std::endl;
1850 for (UN T=0; T<elements->numberElements(); T++) {
1851
1852 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
1853 detB = B.computeInverse(Binv);
1854 absDetB = std::fabs(detB);
1855
1856 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
1857 applyBTinv( dPhi, dPhiTrans, Binv );
1858
1859 vec3D_dbl_Type dPhiTransDiff( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
1860 applyDiff( dPhiTrans, dPhiTransDiff, diffusionT );
1861
1862 for (UN i=0; i < dPhiTrans[0].size(); i++) {
1863 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
1864 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
1865
1866 for (UN j=0; j < value.size(); j++) {
1867 for (UN w=0; w<dPhiTrans.size(); w++) {
1868 for (UN d=0; d<dim; d++){
1869 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTransDiff[w][j][d];
1870 }
1871 }
1872 value[j] *= absDetB;
1873 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
1874 if (setZeros_ && std::fabs(value[j]) < myeps_) {
1875 value[j] = 0.;
1876 }
1877 }
1878 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
1879
1880 A->insertGlobalValues( row, indices(), value() );
1881 }
1882
1883
1884 }
1885 if (callFillComplete)
1886 A->fillComplete();
1887
1888}
1889
1890template <class SC, class LO, class GO, class NO>
1891void FE<SC,LO,GO,NO>::applyDiff( vec3D_dbl_Type& dPhiIn,
1892 vec3D_dbl_Type& dPhiOut,
1893 SmallMatrix<SC>& diffT){
1894 UN dim = diffT.size();
1895 for (UN w=0; w<dPhiIn.size(); w++){
1896 for (UN i=0; i < dPhiIn[w].size(); i++) {
1897 for (UN d1=0; d1<dim; d1++) {
1898 for (UN d2=0; d2<dim; d2++) {
1899 dPhiOut[w][i][d1] += dPhiIn[w][i][d2]* diffT[d2][d1];
1900 }
1901 }
1902 }
1903 }
1904}
1905
1906template <class SC, class LO, class GO, class NO>
1907void FE<SC,LO,GO,NO>::assemblyAceGenTPM( MatrixPtr_Type &A00,
1908 MatrixPtr_Type &A01,
1909 MatrixPtr_Type &A10,
1910 MatrixPtr_Type &A11,
1911 MultiVectorPtr_Type &F0,
1912 MultiVectorPtr_Type &F1,
1913 MapPtr_Type &mapRepeated1,
1914 MapPtr_Type &mapRepeated2,
1915 ParameterListPtr_Type parameterList,
1916 MultiVectorPtr_Type u_repeatedNewton,
1917 MultiVectorPtr_Type p_repeatedNewton,
1918 MultiVectorPtr_Type u_repeatedTime,
1919 MultiVectorPtr_Type p_repeatedTime,
1920 bool update,
1921 bool updateHistory)
1922{
1923
1924
1925 std::string tpmType = parameterList->sublist("Parameter").get("TPM Type","Biot");
1926
1927 int dim = domainVec_[0]->getDimension();
1928 int idata = 1; //= we should init this
1929 int ic = -1; int ng = -1;
1930
1931 //ed.hp:history previous (timestep); previous solution (velocity and acceleration)
1932 //ed.ht:? same length as hp
1933 ElementsPtr_Type elements1 = domainVec_[0]->getElementsC();
1934 ElementsPtr_Type elements2 = domainVec_[1]->getElementsC();
1935
1936 int sizeED = 24; /* 2D case for P2 elements:
1937 12 velocities, 12 accelerations (2 dof per P2 node)
1938 */
1939 if (dim==3)
1940 sizeED = 60;/* 3D case for P2 elements:
1941 30 velocities, 30 accelerations (3 dof per P2 node)
1942 */
1943 if (ed_.size()==0){
1944 for (UN T=0; T<elements1->numberElements(); T++)
1945 ed_.push_back( Teuchos::rcp(new DataElement( sizeED )) );
1946 }
1947
1948 std::vector<ElementSpec> es_vec( parameterList->sublist("Parameter").get("Number of materials",1) , ElementSpec());
1949 vec2D_dbl_Type dataVec( parameterList->sublist("Parameter").get("Number of materials",1), vec_dbl_Type(6,0.) );
1950
1951 for (int i=0; i<dataVec.size(); i++) {
1952 if (tpmType == "Biot") {
1953 if (dim==2) {
1954 dataVec[i][0] = parameterList->sublist("Timestepping Parameter").get("Newmark gamma",0.5);
1955 dataVec[i][1] = parameterList->sublist("Timestepping Parameter").get("Newmark beta",0.25);
1956 dataVec[i][2] = parameterList->sublist("Parameter").get("initial volume fraction solid material"+std::to_string(i+1),0.5); //do we need this?
1957 dataVec[i][3] = parameterList->sublist("Parameter").get("Darcy parameter material"+std::to_string(i+1),1.e-2);
1958 dataVec[i][4] = parameterList->sublist("Parameter").get("Youngs modulus material"+std::to_string(i+1),60.e6);
1959 dataVec[i][5] = parameterList->sublist("Parameter").get("Poisson ratio material"+std::to_string(i+1),0.3);
1960 }
1961 else if (dim==3) {
1962 dataVec[i].resize(12);
1963 dataVec[i][0] = parameterList->sublist("Parameter").get("Youngs modulus material"+std::to_string(i+1),2.e5);
1964 dataVec[i][1] = parameterList->sublist("Parameter").get("Poisson ratio material"+std::to_string(i+1),0.3);
1965 dataVec[i][2] = 0.; //body force x
1966 dataVec[i][3] = 0.; //body force y
1967 dataVec[i][4] = parameterList->sublist("Parameter").get("body force z"+std::to_string(i+1),0.);; //body force z
1968 dataVec[i][5] = parameterList->sublist("Parameter").get("initial volume fraction solid material"+std::to_string(i+1),0.67);
1969 dataVec[i][6] = parameterList->sublist("Parameter").get("Darcy parameter material"+std::to_string(i+1),0.01);
1970 dataVec[i][7] = 2000.; //effective density solid
1971 dataVec[i][8] = 1000.; //effective density fluid?
1972 dataVec[i][9] = 9.81; // gravity
1973 dataVec[i][10] = parameterList->sublist("Timestepping Parameter").get("Newmark gamma",0.5);
1974 dataVec[i][11] = parameterList->sublist("Timestepping Parameter").get("Newmark beta",0.25);
1975 }
1976 }
1977
1978
1979 else if (tpmType == "Biot-StVK") {
1980 dataVec[i][0] = parameterList->sublist("Parameter").get("Youngs modulus material"+std::to_string(i+1),60.e6);
1981 dataVec[i][1] = parameterList->sublist("Parameter").get("Poisson ratio material"+std::to_string(i+1),0.3);
1982 dataVec[i][2] = parameterList->sublist("Parameter").get("initial volume fraction solid material"+std::to_string(i+1),0.5); //do we need this?
1983 dataVec[i][3] = parameterList->sublist("Parameter").get("Darcy parameter material"+std::to_string(i+1),1.e-2);
1984 dataVec[i][4] = parameterList->sublist("Timestepping Parameter").get("Newmark gamma",0.5);
1985 dataVec[i][5] = parameterList->sublist("Timestepping Parameter").get("Newmark beta",0.25);
1986 }
1987 }
1988
1989 for (int i=0; i<es_vec.size(); i++){
1990 if(tpmType == "Biot"){
1991 if (dim==2)
1992 this->SMTSetElSpecBiot(&es_vec[i] ,&idata, ic, ng, dataVec[i]);
1993 else if(dim==3)
1994 this->SMTSetElSpecBiot3D(&es_vec[i] ,&idata, ic, ng, dataVec[i]);
1995 }
1996 else if(tpmType == "Biot-StVK")
1997 this->SMTSetElSpecBiotStVK(&es_vec[i] ,&idata, ic, ng, dataVec[i]);
1998 }
1999 LO elementSizePhase = elements1->nodesPerElement();
2000 LO sizePhase = dim * elementSizePhase;
2001 LO sizePressure = elements2->nodesPerElement();
2002 GO sizePhaseGlobal = A00->getMap()->getMaxAllGlobalIndex()+1;
2003 int workingVectorSize;
2004 if(tpmType == "Biot"){
2005 if (dim==2)
2006 workingVectorSize = 5523;
2007 else if(dim==3)
2008 workingVectorSize = 1817;
2009 }
2010 else if(tpmType == "Biot-StVK")
2011 workingVectorSize = 5223;
2012
2013 double* v = new double [workingVectorSize];
2014
2015 // nd sind Nodalwerte, Anzahl an structs in nd sollte den Knoten entsprechen, bei P2-P1 in 2D also 9
2016 // In X stehen die Koordinaten, X[0] ist x-Koordinate, X[1] ist y-Koordinate, etc.
2017 // nd->X[0]
2018 // at ist die Loesung im letzten Newtonschritt.
2019 // nd[0]->at[0];
2020 // ap ist die Loesung im letzten Zeitschritt.
2021 // nd[0]->ap[0]
2022 // rdata ist die Zeitschrittweite, RD_TimeIncrement wird in sms.h definiert, entsprechend wird auch die Laenge von rdata dort definiert. Standard 400, aber auch nicht gesetzt. Wert muss selber initialisiert werden; eventuell kuerzer moeglich.
2023
2024 std::vector<double> rdata(RD_TimeIncrement+1, 0.);
2025
2026 rdata[RD_TimeIncrement] = parameterList->sublist("Timestepping Parameter").get("dt",0.01);
2027
2028 NodeSpec *ns=NULL;//dummy not need in SKR
2029
2030 NodeData** nd = new NodeData*[ elementSizePhase + sizePressure ];
2031
2032 for (int i=0; i<elementSizePhase + sizePressure; i++){
2033 nd[i] = new NodeData();
2034 }
2035
2036 int numNodes = elementSizePhase + sizePressure;
2037
2038 vec2D_dbl_Type xFull( numNodes, vec_dbl_Type(dim,0.) );
2039 vec2D_dbl_Type atFull( numNodes, vec_dbl_Type(dim,0.) );
2040 vec2D_dbl_Type apFull( numNodes, vec_dbl_Type(dim,0.) );
2041
2042 for (int i=0; i<elementSizePhase + sizePressure; i++) {
2043 nd[i]->X = &(xFull[i][0]);
2044 nd[i]->at = &(atFull[i][0]);
2045 nd[i]->ap = &(apFull[i][0]);
2046 }
2047
2048 GO offsetMap1 = dim * mapRepeated1->getMaxAllGlobalIndex()+1;
2049 vec2D_dbl_ptr_Type pointsRepU = domainVec_.at(0)->getPointsRepeated();
2050 vec2D_dbl_ptr_Type pointsRepP = domainVec_.at(1)->getPointsRepeated();
2051
2052 Teuchos::ArrayRCP< const SC > uArrayNewton = u_repeatedNewton->getData(0);
2053 Teuchos::ArrayRCP< const SC > pArrayNewton = p_repeatedNewton->getData(0);
2054 Teuchos::ArrayRCP< const SC > uArrayTime = u_repeatedTime->getData(0);
2055 Teuchos::ArrayRCP< const SC > pArrayTime = p_repeatedTime->getData(0);
2056
2057 double** mat = new double*[sizePhase+sizePressure];
2058 for (int i=0; i<sizePhase+sizePressure; i++){
2059 mat[i] = new double[sizePhase+sizePressure];
2060 }
2061
2062 Teuchos::ArrayRCP<SC> fValues0 = F0->getDataNonConst(0);
2063 Teuchos::ArrayRCP<SC> fValues1 = F1->getDataNonConst(0);
2064
2065 // Element loop
2066
2067 ElementData ed = ElementData();
2068 for (UN T=0; T<elements1->numberElements(); T++) {
2069
2070 std::vector<double> tmpHp = ed_[T]->getHp(); // Dies sind die alten Daten
2071 std::vector<double> tmpHt = ed_[T]->getHt(); // Dies sind die neuen Daten nachdem das Element aufgerufen wurde, wir hier eigentlich nicht als Variable in ed_ benoetigt.
2072 ed.hp = &tmpHp[0];
2073 ed.ht = &tmpHt[0];
2074
2075 int materialFlag = elements1->getElement(T).getFlag();
2076 TEUCHOS_TEST_FOR_EXCEPTION( materialFlag>es_vec.size()-1, std::runtime_error, "There are not enought material parameters initialized." ) ;
2077 int counter=0;
2078 //Newtonloesung at und Zeitschrittloesung ap
2079 for (int j=0; j<elementSizePhase; j++) {
2080 for (int d=0; d<dim; d++) {
2081 LO index = dim * elements1->getElement(T).getNode(j)+d;//dim * elements1->at(T).at( j ) + d;
2082 atFull[j][d] = uArrayNewton[index];
2083 apFull[j][d] = uArrayTime[index];
2084 }
2085 }
2086 for (int j=0; j<sizePressure; j++) {
2087 LO index = elements2->getElement(T).getNode(j);//elements2->at(T).at( j );
2088 atFull[elementSizePhase+j][0] = pArrayNewton[index];
2089 apFull[elementSizePhase+j][0] = pArrayTime[index];
2090 }
2091
2092 //Nodes
2093 for (int j=0; j<elementSizePhase; j++ ) {
2094 LO index = elements1->getElement(T).getNode(j);
2095 for (int d=0; d<dim; d++) {
2096 xFull[j][d] = (*pointsRepU)[index][d];
2097 }
2098 }
2099 for (int j=0; j<sizePressure; j++ ) {
2100 LO index = elements2->getElement(T).getNode(j);
2101 for (int d=0; d<dim; d++) {
2102 xFull[elementSizePhase+j][d] = (*pointsRepP)[index][d];
2103 }
2104 }
2105 vec_dbl_Type p( sizePhase+sizePressure , 0. );
2106
2107 for (int i=0; i<sizePhase+sizePressure; i++){
2108 for (int j=0; j<sizePhase+sizePressure; j++)
2109 mat[i][j] = 0.;
2110 }
2111 // element assembly
2112 if(tpmType == "Biot"){
2113 if(dim==2)
2114 this->SKR_Biot( v, &es_vec[materialFlag], &ed, &ns, nd , &rdata[0], &idata, &p[0], mat );
2115 else if (dim==3)
2116 this->SKR_Biot3D( v, &es_vec[materialFlag], &ed, &ns, nd , &rdata[0], &idata, &p[0], mat );
2117 }
2118 else if(tpmType == "Biot-StVK")
2119 this->SKR_Biot_StVK( v, &es_vec[materialFlag], &ed, &ns, nd , &rdata[0], &idata, &p[0], mat );
2120
2121 if (updateHistory)
2122 ed_[T]->setHp( ed.ht );
2123
2124 if (update) {
2125
2126 // A00 & A01
2127 for (UN i=0; i < sizePhase; i++) {
2128 Teuchos::Array<SC> value00( sizePhase, 0. );
2129 Teuchos::Array<GO> indices00( sizePhase, 0 );
2130 for (UN j=0; j < value00.size(); j++) {
2131
2132 value00[j] = mat[i][j];
2133
2134 LO tmpJ = j/dim;
2135 LO index = elements1->getElement(T).getNode(tmpJ);
2136 if (j%dim==0)
2137 indices00[j] = dim * mapRepeated1->getGlobalElement( index );
2138 else if (j%dim==1)
2139 indices00[j] = dim * mapRepeated1->getGlobalElement( index ) + 1;
2140 else if (j%dim==2)
2141 indices00[j] = dim * mapRepeated1->getGlobalElement( index ) + 2;
2142 }
2143
2144 Teuchos::Array<SC> value01( sizePressure, 0. );
2145 Teuchos::Array<GO> indices01( sizePressure, 0 );
2146
2147 for (UN j=0; j < value01.size(); j++) {
2148 value01[j] = mat[i][sizePhase+j];
2149 LO index = elements2->getElement(T).getNode(j);
2150 indices01[j] = mapRepeated2->getGlobalElement( index );
2151 }
2152
2153 GO row;
2154 LO tmpI = i/dim;
2155 LO index = elements1->getElement(T).getNode(tmpI);
2156 if (i%dim==0)
2157 row = dim * mapRepeated1->getGlobalElement( index );
2158 else if (i%dim==1)
2159 row = dim * mapRepeated1->getGlobalElement( index ) + 1;
2160 else if (i%dim==2)
2161 row = dim * mapRepeated1->getGlobalElement( index ) + 2;
2162
2163 A00->insertGlobalValues( row, indices00(), value00() );
2164 A01->insertGlobalValues( row, indices01(), value01() );
2165
2166 if (i%dim==0)
2167 fValues0[ dim*index ] += p[ i ];
2168 else if (i%dim==1)
2169 fValues0[ dim*index+1 ] += p[ i ];
2170 else if (i%dim==2)
2171 fValues0[ dim*index+2 ] += p[ i ];
2172 }
2173 // A10 & A11
2174 for (UN i=0; i < sizePressure; i++) {
2175 Teuchos::Array<SC> value10( sizePhase , 0. );
2176 Teuchos::Array<GO> indices10( sizePhase , 0 );
2177 for (UN j=0; j < value10.size(); j++) {
2178 value10[j] = mat[sizePhase+i][j];
2179
2180 LO tmpJ = j/dim;
2181 LO index = elements1->getElement(T).getNode(tmpJ);
2182 if (j%dim==0)
2183 indices10[j] = dim * mapRepeated1->getGlobalElement( index );
2184 else if (j%dim==1)
2185 indices10[j] = dim * mapRepeated1->getGlobalElement( index ) + 1;
2186 else if (j%dim==2)
2187 indices10[j] = dim * mapRepeated1->getGlobalElement( index ) + 2;
2188 }
2189
2190 Teuchos::Array<SC> value11( sizePressure, 0. );
2191 Teuchos::Array<GO> indices11( sizePressure, 0 );
2192 for (UN j=0; j < value11.size(); j++) {
2193 value11[j] = mat[sizePhase+i][sizePhase+j];
2194
2195 LO index = elements2->getElement(T).getNode(j);
2196 indices11[j] = mapRepeated2->getGlobalElement( index );
2197 }
2198
2199
2200 LO index2 = elements2->getElement(T).getNode(i);
2201 GO row = mapRepeated2->getGlobalElement( index2 );
2202 A10->insertGlobalValues( row, indices10(), value10() );
2203 A11->insertGlobalValues( row, indices11(), value11() );
2204
2205 fValues1[ index2 ] += p[ sizePhase + i ];
2206 }
2207 }
2208 }
2209
2210 for (int i=0; i<sizePhase+sizePressure; i++)
2211 delete [] mat[i];
2212 delete [] mat;
2213
2214 delete [] v;
2215
2216 for (int i=0; i<elementSizePhase+sizePressure; i++)
2217 delete nd[i];
2218
2219 delete [] nd;
2220
2221
2222 A00->fillComplete( A00->getMap("row"), A00->getMap("row") );
2223 A01->fillComplete( A10->getMap("row"), A00->getMap("row") );
2224 A10->fillComplete( A00->getMap("row"), A10->getMap("row") );
2225 A11->fillComplete( A10->getMap("row"), A10->getMap("row") );
2226
2227}
2228
2229template <class SC, class LO, class GO, class NO>
2230void FE<SC,LO,GO,NO>::assemblyMass(int dim,
2231 std::string FEType,
2232 std::string fieldType,
2233 MatrixPtr_Type &A,
2234 bool callFillComplete){
2235
2236 TEUCHOS_TEST_FOR_EXCEPTION( FEType == "P0", std::logic_error, "Not implemented for P0" );
2237 UN FEloc = checkFE(dim,FEType);
2238 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2239
2240 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2241
2242 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2243
2244 vec2D_dbl_ptr_Type phi;
2245 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2246
2247 // inner( phi_i , phi_j ) has twice the polyonimial degree than phi_i and phi_j, respectively.
2248 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv0);
2249
2250 Helper::getPhi( phi, weights, dim, FEType, deg );
2251
2252 SC detB;
2253 SC absDetB;
2254 SmallMatrix<SC> B(dim);
2255 GO glob_i, glob_j;
2256 vec_dbl_Type v_i(dim);
2257 vec_dbl_Type v_j(dim);
2258
2259 for (UN T=0; T<elements->numberElements(); T++) {
2260
2261 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
2262 detB = B.computeDet( );
2263 absDetB = std::fabs(detB);
2264
2265 for (UN i=0; i < phi->at(0).size(); i++) {
2266 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
2267 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
2268 for (UN j=0; j < value.size(); j++) {
2269 for (UN w=0; w<phi->size(); w++) {
2270 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
2271
2272 }
2273 value[j] *= absDetB;
2274 if (!fieldType.compare("Scalar")) {
2275 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2276 }
2277
2278 }
2279 if (!fieldType.compare("Scalar")) {
2280 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2281 A->insertGlobalValues( row, indices(), value() );
2282 }
2283 else if (!fieldType.compare("Vector")) {
2284 for (UN d=0; d<dim; d++) {
2285 for (int j=0; j<indices.size(); j++) {
2286 indices[j] = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2287 }
2288 GO row = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2289 A->insertGlobalValues( row, indices(), value() );
2290 }
2291 }
2292 else
2293 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Specify valid vieldType for assembly of mass matrix.");
2294 }
2295
2296 }
2297
2298 if (callFillComplete)
2299 A->fillComplete();
2300}
2301
2302
2303// Ueberladung der Assemblierung der Massematrix fuer FSI, da
2304// checkFE sonst auch fuer das Strukturproblem FEloc = 1 liefert (= Fluid)
2305// und somit die welche domain und Map in der Assemblierung genutzt wird.
2306template <class SC, class LO, class GO, class NO>
2307void FE<SC,LO,GO,NO>::assemblyMass(int dim,
2308 std::string FEType,
2309 std::string fieldType,
2310 MatrixPtr_Type &A,
2311 int FEloc, // 0 = Fluid, 2 = Struktur
2312 bool callFillComplete){
2313
2314 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
2315
2316 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2317
2318 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2319
2320 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2321
2322 vec2D_dbl_ptr_Type phi;
2323 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2324
2325 // inner( phi_i , phi_j ) has twice the polyonimial degree than phi_i and phi_j, respectively.
2326 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv0);
2327
2328 Helper::getPhi( phi, weights, dim, FEType, deg );
2329
2330 SC detB;
2331 SC absDetB;
2332 SmallMatrix<SC> B(dim);
2333 GO glob_i, glob_j;
2334 vec_dbl_Type v_i(dim);
2335 vec_dbl_Type v_j(dim);
2336
2337 for (UN T=0; T<elements->numberElements(); T++) {
2338
2339 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
2340 detB = B.computeDet( );
2341 absDetB = std::fabs(detB);
2342
2343 for (UN i=0; i < phi->at(0).size(); i++) {
2344 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
2345 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
2346 for (UN j=0; j < value.size(); j++) {
2347 for (UN w=0; w<phi->size(); w++) {
2348 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
2349 }
2350 value[j] *= absDetB;
2351 if (!fieldType.compare("Scalar")) {
2352 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2353 }
2354
2355 }
2356 if (!fieldType.compare("Scalar")) {
2357 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2358 A->insertGlobalValues( row, indices(), value() );
2359 }
2360 else if (!fieldType.compare("Vector")) {
2361 for (UN d=0; d<dim; d++) {
2362 for (int j=0; j<indices.size(); j++) {
2363 indices[j] = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2364 }
2365 GO row = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2366 A->insertGlobalValues( row, indices(), value() );
2367 }
2368 }
2369 else
2370 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Specify valid vieldType for assembly of mass matrix.");
2371 }
2372
2373
2374 }
2375 if (callFillComplete)
2376 A->fillComplete();
2377}
2378
2379
2380template <class SC, class LO, class GO, class NO>
2381void FE<SC,LO,GO,NO>::assemblyLaplace(int dim,
2382 std::string FEType,
2383 int degree,
2384 MatrixPtr_Type &A,
2385 bool callFillComplete,
2386 int FELocExternal){
2387 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
2388 UN FEloc;
2389 if (FELocExternal<0)
2390 FEloc = checkFE(dim,FEType);
2391 else
2392 FEloc = FELocExternal;
2393
2394 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2395
2396 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2397
2398 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2399
2400 vec3D_dbl_ptr_Type dPhi;
2401 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2402
2403 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2404 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2405
2406 SC detB;
2407 SC absDetB;
2408 SmallMatrix<SC> B(dim);
2409 SmallMatrix<SC> Binv(dim);
2410 GO glob_i, glob_j;
2411 vec_dbl_Type v_i(dim);
2412 vec_dbl_Type v_j(dim);
2413
2414 for (UN T=0; T<elements->numberElements(); T++) {
2415
2416 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
2417 detB = B.computeInverse(Binv);
2418 absDetB = std::fabs(detB);
2419
2420 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
2421 applyBTinv( dPhi, dPhiTrans, Binv );
2422 for (UN i=0; i < dPhiTrans[0].size(); i++) {
2423 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
2424 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
2425 for (UN j=0; j < value.size(); j++) {
2426 for (UN w=0; w<dPhiTrans.size(); w++) {
2427 for (UN d=0; d<dim; d++){
2428 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTrans[w][j][d];
2429 }
2430 }
2431 value[j] *= absDetB;
2432 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2433 }
2434 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2435
2436 A->insertGlobalValues( row, indices(), value() );
2437 }
2438
2439
2440 }
2441 if (callFillComplete)
2442 A->fillComplete();
2443
2444}
2445
2446template <class SC, class LO, class GO, class NO>
2447void FE<SC,LO,GO,NO>::assemblyLaplaceVecField(int dim,
2448 std::string FEType,
2449 int degree,
2450 MatrixPtr_Type &A,
2451 bool callFillComplete){
2452
2453 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P1-disc" || FEType == "P0",std::logic_error, "Not implemented for P0 or P1-disc");
2454 UN FEloc = checkFE(dim,FEType);
2455
2456 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2457
2458 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2459
2460 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2461
2462 vec3D_dbl_ptr_Type dPhi;
2463 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2464
2465 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2466
2467 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2468
2469 SC detB;
2470 SC absDetB;
2471 SmallMatrix<SC> B(dim);
2472 SmallMatrix<SC> Binv(dim);
2473 GO glob_i, glob_j;
2474 vec_dbl_Type v_i(dim);
2475 vec_dbl_Type v_j(dim);
2476
2477
2478 for (UN T=0; T<elements->numberElements(); T++) {
2479
2480 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
2481 detB = B.computeInverse(Binv);
2482 absDetB = std::fabs(detB);
2483
2484 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
2485 applyBTinv( dPhi, dPhiTrans, Binv );
2486
2487 for (UN i=0; i < dPhiTrans[0].size(); i++) {
2488 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
2489 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
2490 for (UN j=0; j < value.size(); j++) {
2491 for (UN w=0; w<dPhiTrans.size(); w++) {
2492 for (UN d=0; d<dim; d++)
2493 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTrans[w][j][d];
2494 }
2495 value[j] *= absDetB;
2496 if (setZeros_ && std::fabs(value[j]) < myeps_) {
2497 value[j] = 0.;
2498 }
2499 }
2500 for (UN d=0; d<dim; d++) {
2501 for (UN j=0; j < indices.size(); j++)
2502 indices[j] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2503
2504 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2505 A->insertGlobalValues( row, indices(), value() );
2506 }
2507 }
2508 }
2509 if (callFillComplete)
2510 A->fillComplete();
2511}
2512//this assembly used blas matrix-matrix multiplications. It determines the local stiffness matrix at once, but has some overhead due to zero off-diagonal blocks which are computed.
2513template <class SC, class LO, class GO, class NO>
2514void FE<SC,LO,GO,NO>::assemblyLaplaceVecFieldV2(int dim,
2515 std::string FEType,
2516 int degree,
2517 MatrixPtr_Type &A,
2518 bool callFillComplete){
2519
2520 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
2521 UN FEloc = checkFE(dim,FEType);
2522
2523 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2524
2525 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2526
2527 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2528
2529 vec3D_dbl_ptr_Type dPhi;
2530 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2531
2532 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2533
2534 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2535
2536 Teuchos::BLAS<int, SC> teuchosBLAS;
2537
2538 int nmbQuadPoints = dPhi->size();
2539 int nmbScalarDPhi = dPhi->at(0).size();
2540 int nmbAllDPhi = nmbScalarDPhi * dim;
2541 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
2542 int sizeLocStiff = dim*dim;
2543 Teuchos::Array<SmallMatrix<double> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<double>(dim) );
2544 this->buildFullDPhi( dPhi, dPhiMat ); //builds matrix from gradient of scalar phi
2545
2546
2547 SC detB;
2548 SC absDetB;
2549 SmallMatrix<SC> B(dim);
2550 SmallMatrix<SC> Binv(dim);
2551 GO glob_i, glob_j;
2552 vec_dbl_Type v_i(dim);
2553 vec_dbl_Type v_j(dim);
2554
2555 for (UN T=0; T<elements->numberElements(); T++) {
2556
2557 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
2558 detB = B.computeInverse(Binv);
2559 absDetB = std::fabs(detB);
2560
2561 Teuchos::Array<SmallMatrix<double> > allDPhiMatTrans( dPhiMat.size(), SmallMatrix<double>() );
2562
2563 for (int i=0; i<allDPhiMatTrans.size(); i++) {
2564 SmallMatrix<double> res = dPhiMat[i] * Binv;
2565 allDPhiMatTrans[i] = res;
2566 }
2567
2568 SmallMatrix<double> locStiffMat( nmbAllDPhi, 0. );
2569
2570 for (int p=0; p<nmbQuadPoints; p++){
2571
2572 double* allDPhiBlas = new double[ nmbAllDPhi * sizeLocStiff ];
2573
2574 int offset = p * nmbAllDPhi;
2575 int offsetInArray = 0;
2576 for (int i=0; i<nmbAllDPhi; i++) {
2577 fillMatrixArray( allDPhiMatTrans[ offset + i ], allDPhiBlas, "rows",offsetInArray );
2578 offsetInArray += sizeLocStiff;
2579 }
2580
2581 double* locStiffMatBlas = new double[ nmbAllDPhi * nmbAllDPhi ];
2582
2583 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff/*lda of A not trans(A)! Otherwise result is wrong*/, allDPhiBlas, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
2584
2585 for (int i=0; i<nmbAllDPhi; i++) {
2586 for (int j=0; j<nmbAllDPhi; j++) {
2587 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
2588 }
2589 }
2590
2591 delete [] allDPhiBlas;
2592 delete [] locStiffMatBlas;
2593
2594 }
2595
2596 for (UN i=0; i < nmbScalarDPhi; i++) {
2597 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
2598 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
2599 for (UN d=0; d<dim; d++) {
2600 for (UN j=0; j < nmbScalarDPhi; j++){
2601 value[ j * dim + d ] = absDetB * locStiffMat[dim * i + d][j];
2602 indices[ j * dim + d ] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2603 }
2604 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2605 A->insertGlobalValues( row, indices(), value() );
2606 }
2607 }
2608 }
2609 if (callFillComplete)
2610 A->fillComplete();
2611}
2612
2628
2629template <class SC, class LO, class GO, class NO>
2631 int dim, std::string FEType, int degree, MultiVectorPtr_Type u_rep,
2632 BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec,
2633 ParameterListPtr_Type params, std::string assembleMode, bool callFillComplete,
2634 int FELocExternal) {
2635
2636 ElementsPtr_Type elements = this->domainVec_.at(0)->getElementsC();
2637
2638 // Only scalar laplace
2639 int dofs = 1;
2640
2641 vec2D_dbl_ptr_Type pointsRep = this->domainVec_.at(0)->getPointsRepeated();
2642 MapConstPtr_Type map = this->domainVec_.at(0)->getMapRepeated();
2643
2644 vec_dbl_Type solution_u;
2645 vec_dbl_ptr_Type rhsVec;
2646
2647 int numNodes = 3;
2648 if (FEType == "P2") {
2649 numNodes = 6;
2650 }
2651 if (dim == 3) {
2652 numNodes = 4;
2653 if (FEType == "P2") {
2654 numNodes = 10;
2655 }
2656 }
2657
2658 // Tupel construction follows follwing pattern:
2659 // std::string: Physical Entity (i.e. Velocity) , std::string: Discretisation (i.e.
2660 // "P2"), int: Degrees of Freedom per Node, int: Number of Nodes per
2661 // element)
2662 tuple_disk_vec_ptr_Type problemDisk =
2663 Teuchos::rcp(new tuple_disk_vec_Type(0));
2664 tuple_ssii_Type temp("Solution", FEType, dofs, numNodes);
2665 problemDisk->push_back(temp);
2666
2667 // Construct an assembler for each element if not already done
2668 if (assemblyFEElements_.size() == 0) {
2669 initAssembleFEElements("NonLinearLaplace", problemDisk, elements, params, pointsRep, domainVec_.at(0)->getElementMap());
2670 } else if (assemblyFEElements_.size() != elements->numberElements()) {
2671 TEUCHOS_TEST_FOR_EXCEPTION(
2672 true, std::logic_error,
2673 "Number Elements not the same as number assembleFE elements.");
2674 }
2675
2676 MultiVectorPtr_Type resVec_u;
2677 BlockMultiVectorPtr_Type resVecRep;
2678
2679 if (assembleMode != "Rhs") {
2680 // add new or overwrite existing block (0,0) of system matrix
2681 // This is done in specific problem class for most other problems
2682 // Placing it here instead as more fitting
2683 auto A_block_zero_zero = Teuchos::rcp(
2684 new Matrix_Type(this->domainVec_.at(0)->getMapUnique(), this->domainVec_.at(0)->getApproxEntriesPerRow()));
2685
2686 A->addBlock(A_block_zero_zero, 0, 0);
2687 } else {
2688 // Or same for the residual vector
2689 resVec_u = Teuchos::rcp(new MultiVector_Type(map, 1));
2690 resVecRep = Teuchos::rcp(new BlockMultiVector_Type(1));
2691 resVecRep->addBlock(resVec_u, 0);
2692 }
2693 // Call assembly routines on each element
2694 for (UN T = 0; T < assemblyFEElements_.size(); T++) {
2695 vec_dbl_Type solution(0);
2696
2697 // Update solution on the element
2698 solution_u = getSolution(elements->getElement(T).getVectorNodeList(),
2699 u_rep, dofs);
2700 solution.insert(solution.end(), solution_u.begin(), solution_u.end());
2701 assemblyFEElements_[T]->updateSolution(solution);
2702
2703 if (assembleMode == "Jacobian") {
2704 SmallMatrixPtr_Type elementMatrix;
2705 assemblyFEElements_[T]->assembleJacobian();
2706 elementMatrix = assemblyFEElements_[T]->getJacobian();
2707 // Insert (additive) the local element Jacobian into the global
2708 // matrix
2709 assemblyFEElements_[T]
2710 ->advanceNewtonStep(); // n genereal non linear solver step
2711 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0,
2712 problemDisk);
2713 }
2714
2715 if (assembleMode == "Rhs") {
2716 assemblyFEElements_[T]->assembleRHS();
2717 rhsVec = assemblyFEElements_[T]->getRHS();
2718 // Name RHS comes from solving linear systems
2719 // For nonlinear systems RHS synonymous to residual
2720 // Insert (additive) the updated residual into the global residual
2721 // vector
2722 addFeBlockMv(resVecRep, rhsVec, elements->getElement(T), dofs);
2723 }
2724 }
2725 if (callFillComplete && assembleMode != "Rhs") {
2726 // Signal that editing A has finished. This causes the entries of A to
2727 // be redistributed across the MPI ranks
2728 A->getBlock(0, 0)->fillComplete(domainVec_.at(0)->getMapUnique(),
2729 domainVec_.at(0)->getMapUnique());
2730 }
2731 if (assembleMode == "Rhs") {
2732 // Export from overlapping residual to unique residual
2733 MultiVectorPtr_Type resVecUnique = Teuchos::rcp(
2734 new MultiVector_Type(domainVec_.at(0)->getMapUnique(), 1));
2735 resVecUnique->putScalar(0.);
2736 resVecUnique->exportFromVector(resVec_u, true, "Add");
2737 resVec->addBlock(resVecUnique, 0);
2738 }
2739}
2740
2741
2742template <class SC, class LO, class GO, class NO>
2743void FE<SC,LO,GO,NO>::assemblyElasticityJacobianAndStressAceFEM(int dim,
2744 std::string FEType,
2745 MatrixPtr_Type &A,
2746 MultiVectorPtr_Type &f,
2747 MultiVectorPtr_Type u,
2748 ParameterListPtr_Type pList,
2749 double C,
2750 bool callFillComplete){
2751 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::runtime_error, "Not implemented for P0");
2752 UN FEloc = checkFE(dim,FEType);
2753
2754
2755 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2756 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2757
2758 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2759 vec3D_dbl_ptr_Type dPhi;
2760 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
2761
2762 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2763
2764 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2765
2766 SC detB;
2767 SC absDetB;
2768 SmallMatrix<SC> B(dim);
2769 SmallMatrix<SC> Binv(dim);
2770
2771 Teuchos::BLAS<int,SC> teuchosBLAS;
2772
2773 int nmbQuadPoints = dPhi->size();
2774 int nmbScalarDPhi = dPhi->at(0).size();
2775 int nmbAllDPhi = nmbScalarDPhi * dim;
2776 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
2777 int sizeLocStiff = dim*dim;
2778 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<SC>(dim) );
2779
2780 this->buildFullDPhi( dPhi, dPhiMat ); //builds matrix from gradient of scalar phi
2781
2782 std::string material_model = pList->sublist("Parameter").get("Material model","Neo-Hooke");
2783
2784 double poissonRatio = pList->sublist("Parameter").get("Poisson Ratio",0.4);
2785 double mue = pList->sublist("Parameter").get("Mu",2.0e+6);
2786 double mue1 = pList->sublist("Parameter").get("Mu1",2.0e+6);
2787 double mue2 = pList->sublist("Parameter").get("Mu2",2.0e+6);
2788 // Berechne daraus nun E (Youngsches Modul) und die erste Lamé-Konstante \lambda
2789 double E = pList->sublist("Parameter").get("E",3.0e+6); // For StVK mue_*2.*(1. + poissonRatio_);
2790 double E1 = pList->sublist("Parameter").get("E1",3.0e+6); // For StVK mue_*2.*(1. + poissonRatio_);
2791 double E2 = pList->sublist("Parameter").get("E2",3.0e+6); // For StVK mue_*2.*(1. + poissonRatio_);
2792
2793 if (material_model=="Saint Venant-Kirchhoff") {
2794 E = mue*2.*(1. + poissonRatio);
2795 E1 = mue1*2.*(1. + poissonRatio);
2796 E2 = mue2*2.*(1. + poissonRatio);
2797 }
2798
2799 // For StVK (poissonRatio*E)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2800 double lambda = (poissonRatio*E)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2801 double lambda1 = (poissonRatio*E1)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2802 double lambda2 = (poissonRatio*E2)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2803
2804 if (dim == 2){
2805 double* v;
2806 if(!material_model.compare("Saint Venant-Kirchhoff"))
2807 v = new double[154];
2808 else
2809 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only Saint Venant-Kirchhoff in 2D.");
2810
2811 double** Pmat = new double*[2];
2812 for (int i=0; i<2; i++)
2813 Pmat[i] = new double[2];
2814
2815 double** F = new double*[2];
2816 for (int i=0; i<2; i++)
2817 F[i] = new double[2];
2818
2819 double**** Amat = new double***[2];
2820 for (int i=0; i<2; i++){
2821 Amat[i] = new double**[2];
2822 for (int j=0; j<2; j++) {
2823 Amat[i][j] = new double*[2];
2824 for (int k=0; k<2; k++)
2825 Amat[i][j][k] = new double[2];
2826 }
2827 }
2828
2829 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
2830
2831 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
2832
2833 Teuchos::Array<int> indices(2);
2834 for (int T=0; T<elements->numberElements(); T++) {
2835
2836 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
2837 detB = B.computeInverse(Binv);
2838 absDetB = std::fabs(detB);
2839
2840 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
2841
2842 for (int i=0; i<all_dPhiMat_Binv.size(); i++) {
2843 SmallMatrix<SC> res = dPhiMat[i] * Binv;
2844 all_dPhiMat_Binv[i] = res;
2845 }
2846
2847 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
2848 std::vector<SC> locStresses( nmbAllDPhi, 0. );
2849 int elementFlag = 0;
2850 for (int p=0; p<nmbQuadPoints; p++){
2851
2852 SmallMatrix<SC> Fmat( dim, 0. );
2853 SmallMatrix<SC> tmpForScaling( dim, 0. );
2854 Fmat[0][0] = 1.; Fmat[1][1] = 1.;
2855
2856 for (int i=0; i<nmbScalarDPhi; i++) {
2857 indices.at(0) = dim * elements->getElement(T).getNode(i);
2858 indices.at(1) = dim * elements->getElement(T).getNode(i) + 1;
2859
2860 for (int j=0; j<dim; j++) {
2861 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ]; //we should not copy here
2862 SC v = uArray[indices.at(j)];
2863 tmpForScaling.scale( v );
2864 Fmat += tmpForScaling;
2865 }
2866 }
2867
2868 for (int i=0; i<Fmat.size(); i++) {
2869 for (int j=0; j<Fmat.size(); j++) {
2870 F[i][j] = Fmat[i][j]; //fix so we dont need to copy.
2871 }
2872 }
2873
2874 elementFlag = elements->getElement(T).getFlag();
2875 if (elementFlag == 1){
2876 lambda = lambda1;
2877 mue = mue1;
2878 E = E1;
2879 }
2880 else if (elementFlag == 2){
2881 lambda = lambda2;
2882 mue = mue2;
2883 E = E2;
2884 }
2885
2886 if ( !material_model.compare("Saint Venant-Kirchhoff") )
2887 stvk2d(v, &lambda, &mue, F, Pmat, Amat);
2888
2889 SmallMatrix<SC> Aloc(dim*dim);
2890 for (int i=0; i<2; i++) {
2891 for (int j=0; j<2; j++) {
2892 for (int k=0; k<2; k++) {
2893 for (int l=0; l<2; l++) {
2894 Aloc[ 2 * i + j ][ 2 * k + l ] = Amat[i][j][k][l];
2895 }
2896 }
2897 }
2898 }
2899
2900 double* aceFEMFunc = new double[ sizeLocStiff * sizeLocStiff ];
2901 double* allDPhiBlas = new double[ nmbAllDPhi * sizeLocStiff ];
2902
2903 //jacobian
2904 double* resTmp = new double[ nmbAllDPhi * sizeLocStiff ];
2905 // all_dPhiMat_Binv: quadpoints -> basisfunction vector field
2906 fillMatrixArray(Aloc, aceFEMFunc, "cols"); //blas uses column-major
2907
2908 int offset = p * nmbAllDPhi;
2909 int offsetInArray = 0;
2910 for (int i=0; i<nmbAllDPhi; i++) {
2911 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas, "rows",offsetInArray );
2912 offsetInArray += sizeLocStiff;
2913 }
2914
2915 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
2916
2917
2918 double* locStiffMatBlas = new double[ nmbAllDPhi * nmbAllDPhi ];
2919
2920 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff/*lda of A not trans(A)! Otherwise result is wrong*/, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
2921
2922 for (int i=0; i<nmbAllDPhi; i++) {
2923 for (int j=0; j<nmbAllDPhi; j++)
2924 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
2925 }
2926
2927 delete [] resTmp;
2928 delete [] locStiffMatBlas;
2929
2930
2931 //stress
2932 double* fArray = new double[ sizeLocStiff ];
2933 for (int i=0; i<dim; i++) {
2934 for (int j=0; j<dim; j++) {
2935 fArray[i * dim + j] = Pmat[i][j]; //is this correct?
2936 }
2937 }
2938
2939 double* res = new double[ nmbAllDPhi ];
2940 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
2941 for (int i=0; i<locStresses.size(); i++) {
2942 locStresses[i] += weights->at(p) * res[i];
2943 }
2944
2945 delete [] res;
2946 delete [] aceFEMFunc;
2947 delete [] allDPhiBlas;
2948 delete [] fArray;
2949 }
2950
2951 for (int i=0; i<nmbScalarDPhi; i++) {
2952 for (int d1=0; d1<dim; d1++) {
2953
2954 LO rowLO = dim * elements->getElement(T).getNode(i) + d1;
2955 SC v = absDetB * locStresses[ dim * i + d1 ];
2956 fValues[rowLO] += v;
2957
2958 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
2959 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
2960 LO counter = 0;
2961 for (UN j=0; j < nmbScalarDPhi; j++){
2962 for (UN d2=0; d2<dim; d2++) {
2963 indices[counter] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
2964 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
2965 counter++;
2966 }
2967 }
2968 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
2969 A->insertGlobalValues( row, indices(), value() );
2970 }
2971 }
2972 }
2973
2974 delete [] v;
2975 for (int i=0; i<2; i++)
2976 delete [] Pmat[i];
2977 delete [] Pmat;
2978 for (int i=0; i<2; i++)
2979 delete [] F[i];
2980 delete [] F;
2981
2982 for (int i=0; i<2; i++){
2983 for (int j=0; j<2; j++) {
2984 for (int k=0; k<2; k++)
2985 delete [] Amat[i][j][k];
2986 delete [] Amat[i][j];
2987 }
2988 delete [] Amat[i];
2989 }
2990 delete [] Amat;
2991
2992
2993 }
2994 else if (dim == 3) {
2995 double* v;
2996 if (!material_model.compare("Neo-Hooke"))
2997 v = new double[466];
2998 else if(!material_model.compare("Mooney-Rivlin"))
2999 v = new double[476];
3000 else if(!material_model.compare("Saint Venant-Kirchhoff"))
3001 v = new double[279];
3002 else{
3003 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only Neo-Hooke, Mooney-Rivlin and Saint Venant-Kirchhoff.");
3004 }
3005
3006 double** Pmat = new double*[3];
3007 for (int i=0; i<3; i++)
3008 Pmat[i] = new double[3];
3009
3010 double** F = new double*[3];
3011 for (int i=0; i<3; i++)
3012 F[i] = new double[3];
3013
3014 double**** Amat = new double***[3];
3015 for (int i=0; i<3; i++){
3016 Amat[i] = new double**[3];
3017 for (int j=0; j<3; j++) {
3018 Amat[i][j] = new double*[3];
3019 for (int k=0; k<3; k++)
3020 Amat[i][j][k] = new double[3];
3021 }
3022 }
3023
3024 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3025
3026 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
3027
3028 Teuchos::Array<int> indices(3);
3029 for (int T=0; T<elements->numberElements(); T++) {
3030
3031 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
3032 detB = B.computeInverse(Binv);
3033 absDetB = std::fabs(detB);
3034
3035 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3036
3037 for (int i=0; i<all_dPhiMat_Binv.size(); i++) {
3038 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3039 all_dPhiMat_Binv[i] = res;
3040 }
3041
3042 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
3043 std::vector<SC> locStresses( nmbAllDPhi, 0. );
3044 int elementFlag = 0;
3045 for (int p=0; p<nmbQuadPoints; p++){
3046
3047 SmallMatrix<SC> Fmat( dim, 0. );
3048 SmallMatrix<SC> tmpForScaling( dim, 0. );
3049 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3050
3051 for (int i=0; i<nmbScalarDPhi; i++) {
3052 indices.at(0) = dim * elements->getElement(T).getNode(i);
3053 indices.at(1) = dim * elements->getElement(T).getNode(i) + 1;
3054 indices.at(2) = dim * elements->getElement(T).getNode(i) + 2;
3055
3056 for (int j=0; j<dim; j++) {
3057 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ]; //we should not copy here
3058 SC v = uArray[indices.at(j)];
3059 tmpForScaling.scale( v );
3060 Fmat += tmpForScaling;
3061 }
3062 }
3063
3064 for (int i=0; i<Fmat.size(); i++) {
3065 for (int j=0; j<Fmat.size(); j++) {
3066 F[i][j] = Fmat[i][j]; //fix so we dont need to copy.
3067 }
3068 }
3069
3070 elementFlag = elements->getElement(T).getFlag();
3071 if (elementFlag == 1){
3072 lambda = lambda1;
3073 mue = mue1;
3074 E = E1;
3075 }
3076 else if (elementFlag == 2){
3077 lambda = lambda2;
3078 mue = mue2;
3079 E = E2;
3080 }
3081
3082 if ( !material_model.compare("Neo-Hooke") )
3083 nh3d(v, &E, &poissonRatio, F, Pmat, Amat);
3084 else if ( !material_model.compare("Mooney-Rivlin") )
3085 mr3d(v, &E, &poissonRatio, &C, F, Pmat, Amat);
3086 else if ( !material_model.compare("Saint Venant-Kirchhoff") )
3087 stvk3d(v, &lambda, &mue, F, Pmat, Amat);
3088
3089 SmallMatrix<SC> Aloc(dim*dim);
3090 for (int i=0; i<3; i++) {
3091 for (int j=0; j<3; j++) {
3092 for (int k=0; k<3; k++) {
3093 for (int l=0; l<3; l++) {
3094 Aloc[ 3 * i + j ][ 3 * k + l ] = Amat[i][j][k][l];
3095 }
3096 }
3097 }
3098 }
3099
3100 double* aceFEMFunc = new double[ sizeLocStiff * sizeLocStiff ];
3101 double* allDPhiBlas = new double[ nmbAllDPhi * sizeLocStiff ];
3102
3103 //jacobian
3104 double* resTmp = new double[ nmbAllDPhi * sizeLocStiff ];
3105 // all_dPhiMat_Binv: quadpoints -> basisfunction vector field
3106 fillMatrixArray(Aloc, aceFEMFunc, "cols"); //blas uses column-major
3107
3108 int offset = p * nmbAllDPhi;
3109 int offsetInArray = 0;
3110 for (int i=0; i<nmbAllDPhi; i++) {
3111 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas, "rows",offsetInArray );
3112 offsetInArray += sizeLocStiff;
3113 }
3114
3115 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
3116
3117
3118 double* locStiffMatBlas = new double[ nmbAllDPhi * nmbAllDPhi ];
3119
3120 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff/*lda of A not trans(A)! Otherwise result is wrong*/, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
3121
3122 for (int i=0; i<nmbAllDPhi; i++) {
3123 for (int j=0; j<nmbAllDPhi; j++)
3124 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
3125 }
3126
3127 delete [] resTmp;
3128 delete [] locStiffMatBlas;
3129
3130
3131 //stress
3132 double* fArray = new double[ sizeLocStiff ];
3133 for (int i=0; i<dim; i++) {
3134 for (int j=0; j<dim; j++) {
3135 fArray[i * dim + j] = Pmat[i][j]; //is this correct?
3136 }
3137 }
3138
3139 double* res = new double[ nmbAllDPhi ];
3140 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
3141 for (int i=0; i<locStresses.size(); i++) {
3142 locStresses[i] += weights->at(p) * res[i];
3143 }
3144
3145 delete [] res;
3146 delete [] aceFEMFunc;
3147 delete [] allDPhiBlas;
3148 delete [] fArray;
3149 }
3150
3151 for (int i=0; i<nmbScalarDPhi; i++) {
3152 for (int d1=0; d1<dim; d1++) {
3153
3154 LO rowLO = dim * elements->getElement(T).getNode(i) + d1;
3155 SC v = absDetB * locStresses[ dim * i + d1 ];
3156 fValues[rowLO] += v;
3157
3158 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
3159 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
3160 LO counter = 0;
3161 for (UN j=0; j < nmbScalarDPhi; j++){
3162 for (UN d2=0; d2<dim; d2++) {
3163 indices[counter] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
3164 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
3165
3166 counter++;
3167 }
3168 }
3169 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
3170 A->insertGlobalValues( row, indices(), value() );
3171 }
3172 }
3173 }
3174
3175 delete [] v;
3176 for (int i=0; i<3; i++)
3177 delete [] Pmat[i];
3178 delete [] Pmat;
3179 for (int i=0; i<3; i++)
3180 delete [] F[i];
3181 delete [] F;
3182
3183 for (int i=0; i<3; i++){
3184 for (int j=0; j<3; j++) {
3185 for (int k=0; k<3; k++)
3186 delete [] Amat[i][j][k];
3187 delete [] Amat[i][j];
3188 }
3189 delete [] Amat[i];
3190 }
3191 delete [] Amat;
3192
3193 }
3194 if (callFillComplete)
3195 A->fillComplete();
3196
3197}
3198
3199
3200template <class SC, class LO, class GO, class NO>
3201void FE<SC,LO,GO,NO>::assemblyElasticityJacobianAceFEM(int dim,
3202 std::string FEType,
3203 MatrixPtr_Type &A,
3204 MultiVectorPtr_Type u,
3205 std::string material_model,
3206 double E,
3207 double nu,
3208 double C,
3209 bool callFillComplete){
3210 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
3211 UN FEloc = checkFE(dim,FEType);
3212
3213 vec2D_int_ptr_Type elements = domainVec_.at(FEloc)->getElements();
3214
3215 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3216
3217 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3218 vec3D_dbl_ptr_Type dPhi;
3219 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3220
3221 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
3222
3223 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3224
3225 SC detB;
3226 SC absDetB;
3227 SmallMatrix<SC> B(dim);
3228 SmallMatrix<SC> Binv(dim);
3229
3230 Teuchos::BLAS<int, SC> teuchosBLAS;
3231
3232 int nmbQuadPoints = dPhi->size();
3233 int nmbScalarDPhi = dPhi->at(0).size();
3234 int nmbAllDPhi = nmbScalarDPhi * dim;
3235 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
3236 int sizeLocStiff = dim*dim;
3237 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<SC>(dim) );
3238
3239 this->buildFullDPhi( dPhi, dPhiMat ); //builds matrix from gradient of scalar phi
3240
3241 if (dim == 2){
3242 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only for 3D.");
3243 }
3244 else if (dim == 3) {
3245
3246 double* v;
3247 if (!material_model.compare("Neo-Hooke"))
3248 v = new double[466];
3249 else if(!material_model.compare("Mooney-Rivlin"))
3250 v = new double[476];
3251 else{
3252 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only Neo-Hooke and Mooney-Rivlin.");
3253 }
3254
3255
3256 double** Pmat = new double*[3];
3257 for (int i=0; i<3; i++)
3258 Pmat[i] = new double[3];
3259
3260 double** F = new double*[3];
3261 for (int i=0; i<3; i++)
3262 F[i] = new double[3];
3263
3264 double**** Amat = new double***[3];
3265 for (int i=0; i<3; i++){
3266 Amat[i] = new double**[3];
3267 for (int j=0; j<3; j++) {
3268 Amat[i][j] = new double*[3];
3269 for (int k=0; k<3; k++)
3270 Amat[i][j][k] = new double[3];
3271 }
3272 }
3273
3274 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3275
3276 Teuchos::Array<int> indices(3);
3277 for (int T=0; T<elements->size(); T++) {
3278
3279 Helper::buildTransformation(elements->at(T), pointsRep, B);
3280 detB = B.computeInverse(Binv);
3281 absDetB = std::fabs(detB);
3282
3283 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3284
3285 for (int i=0; i<all_dPhiMat_Binv.size(); i++) {
3286 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3287 all_dPhiMat_Binv[i] = res;
3288 }
3289
3290 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
3291
3292 for (int p=0; p<nmbQuadPoints; p++){
3293
3294 SmallMatrix<SC> Fmat( dim, 0. );
3295 SmallMatrix<SC> tmpForScaling( dim, 0. );
3296 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3297
3298 for (int i=0; i<nmbScalarDPhi; i++) {
3299 indices.at(0) = dim * elements->at(T).at(i);
3300 indices.at(1) = dim * elements->at(T).at(i) + 1;
3301 indices.at(2) = dim * elements->at(T).at(i) + 2;
3302
3303 for (int j=0; j<dim; j++) {
3304 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ]; //we should not copy here
3305 SC v = uArray[indices.at(j)];
3306 tmpForScaling.scale( v );
3307 Fmat += tmpForScaling;
3308 }
3309 }
3310
3311 for (int i=0; i<Fmat.size(); i++) {
3312 for (int j=0; j<Fmat.size(); j++) {
3313 F[i][j] = Fmat[i][j]; //fix so we dont need to copy.
3314 }
3315 }
3316 if ( !material_model.compare("Neo-Hooke") )
3317 nh3d(v, &E, &nu, F, Pmat, Amat);
3318 else if ( !material_model.compare("Mooney-Rivlin") )
3319 mr3d(v, &E, &nu, &C, F, Pmat, Amat);
3320
3321 SmallMatrix<SC> Aloc(dim*dim);
3322 for (int i=0; i<3; i++) {
3323 for (int j=0; j<3; j++) {
3324 for (int k=0; k<3; k++) {
3325 for (int l=0; l<3; l++) {
3326 Aloc[ 3 * i + j ][ 3 * k + l ] = Amat[i][j][k][l];
3327 }
3328 }
3329 }
3330 }
3331
3332 double* aceFEMFunc = new double[ sizeLocStiff * sizeLocStiff ];
3333 double* allDPhiBlas = new double[ nmbAllDPhi * sizeLocStiff ];
3334 double* resTmp = new double[ nmbAllDPhi * sizeLocStiff ];
3335 // all_dPhiMat_Binv: quadpoints -> basisfunction vector field
3336 fillMatrixArray(Aloc, aceFEMFunc, "cols"); //blas uses column-major
3337
3338 int offset = p * nmbAllDPhi;
3339 int offsetInArray = 0;
3340 for (int i=0; i<nmbAllDPhi; i++) {
3341 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas, "rows",offsetInArray );
3342 offsetInArray += sizeLocStiff;
3343 }
3344
3345 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
3346
3347 double* locStiffMatBlas = new double[ nmbAllDPhi * nmbAllDPhi ];
3348
3349 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff/*lda of A not trans(A)! Otherwise result is wrong*/, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
3350
3351 for (int i=0; i<nmbAllDPhi; i++) {
3352 for (int j=0; j<nmbAllDPhi; j++)
3353 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
3354 }
3355
3356 delete [] aceFEMFunc;
3357 delete [] allDPhiBlas;
3358 delete [] resTmp;
3359 delete [] locStiffMatBlas;
3360
3361 }
3362 for (int i=0; i<nmbScalarDPhi; i++) {
3363 for (int d1=0; d1<dim; d1++) {
3364 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
3365 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
3366 LO counter = 0;
3367 for (UN j=0; j < nmbScalarDPhi; j++){
3368 for (UN d2=0; d2<dim; d2++) {
3369 indices[counter] = GO ( dim * map->getGlobalElement( elements->at(T).at(j) ) + d2 );
3370 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
3371 counter++;
3372 }
3373 }
3374 GO row = GO ( dim * map->getGlobalElement( elements->at(T).at(i) ) + d1 );
3375 A->insertGlobalValues( row, indices(), value() );
3376 }
3377 }
3378 }
3379
3380 delete [] v;
3381 for (int i=0; i<3; i++)
3382 delete [] Pmat[i];
3383 delete [] Pmat;
3384 for (int i=0; i<3; i++)
3385 delete [] F[i];
3386 delete [] F;
3387
3388 for (int i=0; i<3; i++){
3389 for (int j=0; j<3; j++) {
3390 for (int k=0; k<3; k++)
3391 delete [] Amat[i][j][k];
3392 delete [] Amat[i][j];
3393 }
3394 delete [] Amat[i];
3395 }
3396 delete [] Amat;
3397
3398 }
3399 if (callFillComplete)
3400 A->fillComplete();
3401
3402}
3403
3404template <class SC, class LO, class GO, class NO>
3405void FE<SC,LO,GO,NO>::assemblyElasticityStressesAceFEM(int dim,
3406 std::string FEType,
3407 MultiVectorPtr_Type &f,
3408 MultiVectorPtr_Type u,
3409 std::string material_model,
3410 double E,
3411 double nu,
3412 double C,
3413 bool callFillComplete){
3414 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
3415 UN FEloc = checkFE(dim,FEType);
3416
3417 vec2D_int_ptr_Type elements = domainVec_.at(FEloc)->getElements();
3418
3419 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3420
3421 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3422
3423 vec3D_dbl_ptr_Type dPhi;
3424 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3425
3426 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
3427
3428 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3429
3430 SC detB;
3431 SC absDetB;
3432 SmallMatrix<SC> B(dim);
3433 SmallMatrix<SC> Binv(dim);
3434
3435 Teuchos::BLAS<int, SC> teuchosBLAS;
3436
3437 int nmbQuadPoints = dPhi->size();
3438 int nmbScalarDPhi = dPhi->at(0).size();
3439 int nmbAllDPhi = nmbScalarDPhi * dim;
3440 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
3441 int sizeLocStiff = dim*dim;
3442 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<SC>(dim) );
3443
3444 this->buildFullDPhi( dPhi, dPhiMat ); //builds matrix from gradient of scalar phi
3445
3446 if (dim == 2){
3447 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only for 3D.");
3448 }
3449 else if (dim == 3) {
3450
3451 double* v;
3452 if (!material_model.compare("Neo-Hooke"))
3453 v = new double[466];
3454 else if(!material_model.compare("Mooney-Rivlin"))
3455 v = new double[476];
3456 else{
3457 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only Neo-Hooke and Mooney-Rivlin.");
3458 }
3459
3460
3461 double** Pmat = new double*[3];
3462 for (int i=0; i<3; i++)
3463 Pmat[i] = new double[3];
3464
3465 double** F = new double*[3];
3466 for (int i=0; i<3; i++)
3467 F[i] = new double[3];
3468
3469 double**** Amat = new double***[3];
3470 for (int i=0; i<3; i++){
3471 Amat[i] = new double**[3];
3472 for (int j=0; j<3; j++) {
3473 Amat[i][j] = new double*[3];
3474 for (int k=0; k<3; k++)
3475 Amat[i][j][k] = new double[3];
3476 }
3477 }
3478
3479 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3480
3481 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
3482
3483 Teuchos::Array<int> indices(3);
3484 for (int T=0; T<elements->size(); T++) {
3485
3486 Helper::buildTransformation(elements->at(T), pointsRep, B);
3487 detB = B.computeInverse(Binv);
3488 absDetB = std::fabs(detB);
3489
3490 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3491
3492 for (int i=0; i<all_dPhiMat_Binv.size(); i++) {
3493 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3494 all_dPhiMat_Binv[i] = res;
3495 }
3496 std::vector<double> locStresses( nmbAllDPhi, 0. );
3497
3498 for (int p=0; p<nmbQuadPoints; p++){
3499
3500 SmallMatrix<SC> Fmat( dim, 0. );
3501 SmallMatrix<SC> tmpForScaling( dim, 0. );
3502 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3503
3504 for (int i=0; i<nmbScalarDPhi; i++) {
3505 indices.at(0) = dim * elements->at(T).at(i);
3506 indices.at(1) = dim * elements->at(T).at(i) + 1;
3507 indices.at(2) = dim * elements->at(T).at(i) + 2;
3508
3509 for (int j=0; j<dim; j++) {
3510 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ]; //we should not copy here
3511 SC v = uArray[indices.at(j)];
3512 tmpForScaling.scale( v );
3513 Fmat += tmpForScaling;
3514 }
3515 }
3516
3517 for (int i=0; i<Fmat.size(); i++) {
3518 for (int j=0; j<Fmat.size(); j++) {
3519 F[i][j] = Fmat[i][j]; //fix so we dont need to copy.
3520 }
3521 }
3522 if ( !material_model.compare("Neo-Hooke") )
3523 nh3d(v, &E, &nu, F, Pmat, Amat);
3524 else if ( !material_model.compare("Mooney-Rivlin") )
3525 mr3d(v, &E, &nu, &C, F, Pmat, Amat);
3526
3527 double* aceFEMFunc = new double[ sizeLocStiff * sizeLocStiff ];
3528 double* allDPhiBlas = new double[ nmbAllDPhi * sizeLocStiff ];
3529
3530 int offset = p * nmbAllDPhi;
3531 int offsetInArray = 0;
3532 for (int i=0; i<nmbAllDPhi; i++) {
3533 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas, "rows",offsetInArray );
3534 offsetInArray += sizeLocStiff;
3535 }
3536
3537
3538 double* fArray = new double[ sizeLocStiff ];
3539 for (int i=0; i<dim; i++) {
3540 for (int j=0; j<dim; j++) {
3541 fArray[i * dim + j] = Pmat[i][j]; //is this correct?
3542 }
3543 }
3544
3545 double* res = new double[ nmbAllDPhi ];
3546 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
3547 for (int i=0; i<locStresses.size(); i++) {
3548 locStresses[i] += weights->at(p) * res[i];
3549 }
3550
3551 delete [] aceFEMFunc;
3552 delete [] allDPhiBlas;
3553 delete [] fArray;
3554 }
3555
3556
3557
3558 for (int i=0; i<nmbScalarDPhi; i++) {
3559 for (int d1=0; d1<dim; d1++) {
3560 LO row = dim * elements->at(T).at(i) + d1;
3561 SC v = absDetB * locStresses[ dim * i + d1 ];
3562 fValues[row] = v;
3563 }
3564 }
3565 }
3566
3567
3568 delete [] v;
3569 for (int i=0; i<3; i++)
3570 delete [] Pmat[i];
3571 delete [] Pmat;
3572 for (int i=0; i<3; i++)
3573 delete [] F[i];
3574 delete [] F;
3575
3576 for (int i=0; i<3; i++){
3577 for (int j=0; j<3; j++) {
3578 for (int k=0; k<3; k++)
3579 delete [] Amat[i][j][k];
3580 delete [] Amat[i][j];
3581 }
3582 delete [] Amat[i];
3583 }
3584 delete [] Amat;
3585
3586 }
3587}
3588
3590template <class SC, class LO, class GO, class NO>
3592 std::string FEType,
3593 MatrixPtr_Type &A,
3594 MultiVectorPtr_Type u,
3595 bool callFillComplete){
3596
3597 TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
3598 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
3599
3600 UN FEloc = checkFE(dim,FEType);
3601
3602 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
3603
3604 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3605
3606 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3607
3608 vec3D_dbl_ptr_Type dPhi;
3609 vec2D_dbl_ptr_Type phi;
3610 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3611
3612 UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv0); //Elementwise assembly of grad u
3613
3614 UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv1 ) +
3615 Helper::determineDegree( dim, FEType, Helper::Deriv0) +
3616 extraDeg;
3617
3618 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3619 Helper::getPhi(phi, weights, dim, FEType, deg);
3620 SC detB;
3621 SC absDetB;
3622 SmallMatrix<SC> B(dim);
3623 SmallMatrix<SC> Binv(dim);
3624 GO glob_i, glob_j;
3625 vec_dbl_Type v_i(dim);
3626 vec_dbl_Type v_j(dim);
3627
3628 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
3629 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3630
3631 for (UN T=0; T<elements->numberElements(); T++) {
3632
3633 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
3634 detB = B.computeInverse(Binv);
3635 absDetB = std::fabs(detB);
3636
3637 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3638 applyBTinv( dPhi, dPhiTrans, Binv );
3639
3640 for (int w=0; w<phi->size(); w++){ //quads points
3641 for (int d=0; d<dim; d++) {
3642 uLoc[d][w] = 0.;
3643 for (int i=0; i < phi->at(0).size(); i++) {
3644 LO index = dim * elements->getElement(T).getNode(i) + d;
3645 uLoc[d][w] += uArray[index] * phi->at(w).at(i);
3646 }
3647 }
3648 }
3649
3650 for (UN i=0; i < phi->at(0).size(); i++) {
3651 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
3652 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
3653 for (UN j=0; j < value.size(); j++) {
3654 for (UN w=0; w<dPhiTrans.size(); w++) {
3655 for (UN d=0; d<dim; d++){
3656 value[j] += weights->at(w) * uLoc[d][w] * (*phi)[w][i] * dPhiTrans[w][j][d];
3657 }
3658
3659 }
3660 value[j] *= absDetB;
3661 if (setZeros_ && std::fabs(value[j]) < myeps_) {
3662 value[j] = 0.;
3663 }
3664
3665 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) );
3666 GO glob_j = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) );
3667 }
3668 for (UN d=0; d<dim; d++) {
3669 for (UN j=0; j < indices.size(); j++)
3670 indices[j] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
3671
3672 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
3673 A->insertGlobalValues( row, indices(), value() );
3674 }
3675 }
3676 }
3677
3678
3679 if (callFillComplete)
3680 A->fillComplete();
3681}
3682
3684template <class SC, class LO, class GO, class NO>
3686 std::string FEType,
3687 MatrixPtr_Type &A,
3688 MultiVectorPtr_Type u,
3689 bool callFillComplete){
3690
3691 TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
3692 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
3693 UN FEloc = checkFE(dim,FEType);
3694
3695 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
3696
3697 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3698
3699 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3700
3701 vec3D_dbl_ptr_Type dPhi;
3702 vec2D_dbl_ptr_Type phi;
3703 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3704
3705 UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv1); //Elementwise assembly of u
3706
3707 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv0) + extraDeg;
3708
3709 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3710 Helper::getPhi(phi, weights, dim, FEType, deg);
3711
3712 SC detB;
3713 SC absDetB;
3714 SmallMatrix<SC> B(dim);
3715 SmallMatrix<SC> Binv(dim);
3716 GO glob_i, glob_j;
3717 vec_dbl_Type v_i(dim);
3718 vec_dbl_Type v_j(dim);
3719
3720 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3721
3722 for (UN T=0; T<elements->numberElements(); T++) {
3723
3724 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
3725 detB = B.computeInverse(Binv);
3726 absDetB = std::fabs(detB);
3727
3728 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3729 applyBTinv( dPhi, dPhiTrans, Binv );
3730
3731 std::vector<SmallMatrix<SC> > duLoc( weights->size(), SmallMatrix<SC>(dim) ); //for all quad points p_i each matrix is [u_x * grad Phi(p_i), u_y * grad Phi(p_i), u_z * grad Phi(p_i) (if 3D) ], duLoc[w] = [[phixx;phixy],[phiyx;phiyy]] (2D)
3732
3733 for (int w=0; w<dPhiTrans.size(); w++){ //quads points
3734 for (int d1=0; d1<dim; d1++) {
3735 for (int i=0; i < dPhiTrans[0].size(); i++) {
3736 LO index = dim * elements->getElement(T).getNode(i) + d1;
3737 for (int d2=0; d2<dim; d2++)
3738 duLoc[w][d2][d1] += uArray[index] * dPhiTrans[w][i][d2];
3739 }
3740 }
3741 }
3742
3743 for (UN i=0; i < phi->at(0).size(); i++) {
3744 for (UN d1=0; d1<dim; d1++) {
3745 Teuchos::Array<SC> value( dim*phi->at(0).size(), 0. ); //These are value (W_ix,W_iy,W_iz)
3746 Teuchos::Array<GO> indices( dim*phi->at(0).size(), 0 );
3747 for (UN j=0; j < phi->at(0).size(); j++) {
3748 for (UN d2=0; d2<dim; d2++){
3749 for (UN w=0; w<phi->size(); w++) {
3750 value[ dim * j + d2 ] += weights->at(w) * duLoc[w][d2][d1] * (*phi)[w][i] * (*phi)[w][j];
3751 }
3752 value[ dim * j + d2 ] *= absDetB;
3753
3754 if (setZeros_ && std::fabs(value[ dim * j + d2 ]) < myeps_) {
3755 value[ dim * j + d2 ] = 0.;
3756 }
3757 }
3758 }
3759 for (UN j=0; j < phi->at(0).size(); j++){
3760 for (UN d2=0; d2<dim; d2++){
3761 indices[ dim * j + d2 ] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
3762 }
3763 }
3764
3765 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
3766 A->insertGlobalValues( row, indices(), value() );
3767 }
3768 }
3769 }
3770 if (callFillComplete)
3771 A->fillComplete();
3772}
3773
3775template <class SC, class LO, class GO, class NO>
3777 std::string FEType1,
3778 std::string FEType2,
3779 int degree,
3780 MatrixPtr_Type &Bmat,
3781 MatrixPtr_Type &BTmat,
3782 MapConstPtr_Type map1,
3783 MapConstPtr_Type map2,
3784 bool callFillComplete) {
3785
3786
3787 UN FEloc1 = checkFE(dim,FEType1);
3788 UN FEloc2 = checkFE(dim,FEType2);
3789
3790 ElementsPtr_Type elements1 = domainVec_.at(FEloc1)->getElementsC();
3791 ElementsPtr_Type elements2 = domainVec_.at(FEloc2)->getElementsC();
3792
3793 vec2D_dbl_ptr_Type pointsRep1 = domainVec_.at(FEloc1)->getPointsRepeated();
3794
3795 MapConstPtr_Type mapping1 = domainVec_.at(FEloc1)->getMapRepeated();
3796 MapConstPtr_Type mapping2;
3797
3798 if (FEType2 == "P0")
3799 mapping2 = domainVec_.at(FEloc2)->getElementMap();
3800 else
3801 mapping2 = domainVec_.at(FEloc2)->getMapRepeated();
3802
3803 vec3D_dbl_ptr_Type dPhi;
3804 vec2D_dbl_ptr_Type phi;
3805 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3806
3807 UN deg = Helper::determineDegree( dim, FEType1, Helper::Deriv1) +
3809
3810 Helper::getDPhi(dPhi, weights, dim, FEType1, deg);
3811
3812 if (FEType2=="P1-disc-global")
3813 Helper::getPhiGlobal(phi, weights, dim, FEType2, deg);
3814 if (FEType2=="P1-disc" && FEType1=="Q2" )
3815 Helper::getPhi(phi, weights, dim, FEType2, deg, FEType1);
3816 else
3817 Helper::getPhi(phi, weights, dim, FEType2, deg);
3818
3819 SC detB;
3820 SC absDetB;
3821 SmallMatrix<SC> B(dim);
3822 SmallMatrix<SC> Binv(dim);
3823 GO glob_i, glob_j;
3824 vec_dbl_Type v_i(dim);
3825 vec_dbl_Type v_j(dim);
3826
3827 for (UN T=0; T<elements1->numberElements(); T++) {
3828
3829 Helper::buildTransformation(elements1->getElement(T).getVectorNodeList(), pointsRep1, B, FEType1);
3830 detB = B.computeInverse(Binv);
3831 absDetB = std::fabs(detB);
3832
3833 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3834 applyBTinv( dPhi, dPhiTrans, Binv );
3835
3836 for (UN i=0; i < phi->at(0).size(); i++) {
3837 Teuchos::Array<Teuchos::Array<SC> >valueVec( dim, Teuchos::Array<SC>( dPhiTrans[0].size(), 0. ) );
3838 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
3839
3840 for (UN j=0; j < valueVec[0].size(); j++) {
3841 for (UN w=0; w<dPhiTrans.size(); w++) {
3842 for (UN d=0; d<dim; d++)
3843 valueVec[d][j] += weights->at(w) * phi->at(w)[i] * dPhiTrans[w][j][d];
3844 }
3845 for (UN d=0; d<dim; d++){
3846 valueVec[d][j] *= absDetB;
3847 if (setZeros_ && std::fabs(valueVec[d][j]) < myeps_) {
3848 valueVec[d][j] = 0.;
3849 }
3850 }
3851 }
3852 for (UN d=0; d<dim; d++) {
3853 for (UN j=0; j < indices.size(); j++)
3854 indices[j] = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(j) ) + d );
3855
3856 GO row;
3857 if (FEType2=="P0")
3858 row = GO ( mapping2->getGlobalElement( T ) );
3859 else
3860 row = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(i) ) );
3861 Bmat->insertGlobalValues( row, indices(), valueVec[d]() );
3862 }
3863 }
3864
3865 // We compute value twice, maybe we should change this
3866 for (UN i=0; i < dPhiTrans[0].size(); i++) {
3867
3868 Teuchos::Array<Teuchos::Array<SC> >valueVec( dim, Teuchos::Array<SC>( phi->at(0).size(), 0. ) );
3869 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
3870 for (UN j=0; j < valueVec[0].size(); j++) {
3871 for (UN w=0; w<dPhiTrans.size(); w++) {
3872 for (UN d=0; d<dim; d++)
3873 valueVec[d][j] += weights->at(w) * phi->at(w)[j] * dPhiTrans[w][i][d];
3874 }
3875 for (UN d=0; d<dim; d++){
3876 valueVec[d][j] *= absDetB;
3877 if (setZeros_ && std::fabs(valueVec[d][j]) < myeps_) {
3878 valueVec[d][j] = 0.;
3879 }
3880 }
3881 }
3882
3883 for (UN j=0; j < indices.size(); j++){
3884 if (FEType2=="P0")
3885 indices[j] = GO ( mapping2->getGlobalElement( T ) );
3886 else
3887 indices[j] = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(j) ) );
3888 }
3889 for (UN d=0; d<dim; d++) {
3890 GO row = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(i) ) + d );
3891 BTmat->insertGlobalValues( row, indices(), valueVec[d]() );
3892 }
3893
3894 }
3895
3896 }
3897 if (callFillComplete) {
3898 Bmat->fillComplete( map1, map2 );
3899 BTmat->fillComplete( map2, map1 );
3900 }
3901
3902}
3903
3905template <class SC, class LO, class GO, class NO>
3907 std::string FEType1,
3908 std::string FEType2,
3909 int degree,
3910 MatrixPtr_Type &Bmat,
3911 MatrixPtr_Type &BTmat,
3912 MapConstPtr_Type map1,
3913 MapConstPtr_Type map2,
3914 bool callFillComplete) {
3915
3916
3917 UN FEloc1 = checkFE(dim,FEType1);
3918 UN FEloc2 = checkFE(dim,FEType2);
3919
3920 ElementsPtr_Type elements1 = domainVec_.at(FEloc1)->getElementsC();
3921 ElementsPtr_Type elements2 = domainVec_.at(FEloc2)->getElementsC();
3922
3923 vec2D_dbl_ptr_Type pointsRep1 = domainVec_.at(FEloc1)->getPointsRepeated();
3924
3925 MapConstPtr_Type mapping1 = domainVec_.at(FEloc1)->getMapRepeated();
3926 MapConstPtr_Type mapping2;
3927
3928 if (FEType2 == "P0")
3929 mapping2 = domainVec_.at(FEloc2)->getElementMap();
3930 else
3931 mapping2 = domainVec_.at(FEloc2)->getMapRepeated();
3932
3933 vec3D_dbl_ptr_Type dPhi;
3934 vec2D_dbl_ptr_Type phi;
3935 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
3936
3937 UN deg = Helper::determineDegree( dim, FEType1, Helper::Deriv1) +
3939
3940 Helper::getDPhi(dPhi, weights, dim, FEType1, deg);
3941
3942 if (FEType2=="P1-disc-global")
3943 Helper::getPhiGlobal(phi, weights, dim, FEType2, deg);
3944 if (FEType2=="P1-disc" && FEType1=="Q2" )
3945 Helper::getPhi(phi, weights, dim, FEType2, deg, FEType1);
3946 else
3947 Helper::getPhi(phi, weights, dim, FEType2, deg);
3948
3949 SC detB;
3950 SC absDetB;
3951 SmallMatrix<SC> B(dim);
3952 SmallMatrix<SC> Binv(dim);
3953 GO glob_i, glob_j;
3954 vec_dbl_Type v_i(dim);
3955 vec_dbl_Type v_j(dim);
3956
3957 Teuchos::Array<GO> colIndex( 1, 0 );
3958 Teuchos::Array<GO> rowIndex( 1, 0 );
3959 Teuchos::Array<SC> value(1, 0.);
3960
3961 for (UN T=0; T<elements1->numberElements(); T++) {
3962
3963 Helper::buildTransformation(elements1->getElement(T).getVectorNodeList(), pointsRep1, B, FEType1);
3964 detB = B.computeInverse(Binv);
3965 absDetB = std::fabs(detB);
3966
3967 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3968 applyBTinv( dPhi, dPhiTrans, Binv );
3969
3970 for (UN i=0; i < phi->at(0).size(); i++) {
3971 if (FEType2=="P0")
3972 rowIndex[0] = GO ( mapping2->getGlobalElement( T ) );
3973 else
3974 rowIndex[0] = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(i) ) );
3975
3976 for (UN j=0; j < dPhiTrans[0].size(); j++) {
3977 for (UN d=0; d<dim; d++){
3978 value[0] = 0.;
3979 for (UN w=0; w<dPhiTrans.size(); w++)
3980 value[0] += weights->at(w) * phi->at(w)[i] * dPhiTrans[w][j][d];
3981 value[0] *= absDetB;
3982 colIndex[0] = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(j) ) + d );
3983 Bmat->insertGlobalValues( rowIndex[0], colIndex(), value() );
3984 BTmat->insertGlobalValues( colIndex[0], rowIndex(), value() );
3985
3986 }
3987 }
3988 }
3989
3990 }
3991 if (callFillComplete) {
3992 Bmat->fillComplete( map1, map2 );
3993 BTmat->fillComplete( map2, map1 );
3994 }
3995
3996}
3997
3998template <class SC, class LO, class GO, class NO>
4000 std::string FEType,
4001 MatrixPtr_Type &A,
4002 bool callFillComplete){
4003
4004 TEUCHOS_TEST_FOR_EXCEPTION(FEType != "P1",std::logic_error, "Only implemented for P1. Q1 is equivalent but we need to adjust scaling for the reference element.");
4005 UN FEloc = checkFE(dim,FEType);
4006
4007 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4008
4009 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4010
4011 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4012
4013 vec2D_dbl_ptr_Type phi;
4014
4015 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
4016
4017 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv0);
4018
4019 Helper::getPhi( phi, weights, dim, FEType, deg );
4020
4021 SC detB;
4022 SC absDetB;
4023 SmallMatrix<SC> B(dim);
4024 GO glob_i, glob_j;
4025 vec_dbl_Type v_i(dim);
4026 vec_dbl_Type v_j(dim);
4027
4028 SC refElementSize;
4029 SC refElementScale;
4030 if (dim==2) {
4031 refElementSize = 0.5;
4032 refElementScale = 1./9.;
4033 }
4034 else if(dim==3){
4035 refElementSize = 1./6.;
4036 refElementScale = 1./16.;
4037 }
4038 else
4039 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Only implemented for 2D and 3D.");
4040
4041 for (UN T=0; T<elements->numberElements(); T++) {
4042
4043 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4044 detB = B.computeDet( );
4045 absDetB = std::fabs(detB);
4046
4047 for (UN i=0; i < phi->at(0).size(); i++) {
4048 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
4049 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
4050 for (UN j=0; j < value.size(); j++) {
4051 for (UN w=0; w<phi->size(); w++) {
4052 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
4053 }
4054 value[j] *= absDetB;
4055 value[j] -= refElementSize * absDetB * refElementScale;
4056
4057 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
4058 }
4059
4060 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
4061 A->insertGlobalValues( row, indices(), value() );
4062 }
4063
4064 }
4065
4066 if (callFillComplete)
4067 A->fillComplete();
4068}
4069
4070
4071
4072template <class SC, class LO, class GO, class NO>
4074 std::string FEType,
4075 MatrixPtr_Type &A,
4076 CoeffFuncDbl_Type func,
4077 double* parameters,
4078 bool callFillComplete)
4079{
4080 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
4081 int FEloc = this->checkFE(dim,FEType);
4082
4083 DomainConstPtr_Type domain = domainVec_.at(FEloc);
4084 ElementsPtr_Type elements = domain->getElementsC();
4085 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
4086 MapConstPtr_Type map = domain->getMapRepeated();
4087
4088 vec3D_dbl_ptr_Type dPhi;
4089 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(new vec_dbl_Type(0));
4090 vec2D_dbl_ptr_Type quadPts;
4091
4092 // double val, value1_j, value2_j , value1_i, value2_i;
4093
4094 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv1);
4095
4096 Helper::getDPhi(dPhi, weightsDPhi, dim, FEType, deg);
4097 Helper::getQuadratureValues(dim, deg, quadPts, weightsDPhi, FEType);
4098
4099 // SC = double, GO = long, UN = int
4100 SC detB;
4101 SC absDetB;
4102 SmallMatrix<SC> B(dim);
4103 SmallMatrix<SC> Binv(dim);
4104 GO glob_i, glob_j;
4105
4106
4107 vec_dbl_ptr_Type dist = domain->getDistancesToInterface();
4108 if (dim == 2)
4109 {
4110 double val, value1_j, value2_j , value1_i, value2_i;
4111 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
4112
4113 double distance1, distance2, distance3;
4114 vec_dbl_Type distance_mean(1); // Durchschnittliche Distanz des elements T
4115 for (int T = 0; T < elements->numberElements(); T++)
4116 {
4117 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4118 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4119 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4120
4121 distance1 = dist->at(elements->getElement(T).getNode(0));
4122 distance2 = dist->at(elements->getElement(T).getNode(1));
4123 distance3 = dist->at(elements->getElement(T).getNode(2));
4124
4125 distance_mean.at(0) = (distance1 + distance2 + distance3)/3.0; // Mittelwert
4126 double funcvalue = func(&distance_mean.at(0),parameters);
4127
4128 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4129 detB = B.computeInverse(Binv);
4130 absDetB = std::fabs(detB);
4131
4132 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
4133 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4134 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4135
4136 for (int i = 0; i < dPhi->at(0).size(); i++)
4137 {
4138 Teuchos::Array<SC> value( 1, 0. );
4139 Teuchos::Array<GO> indices( 1, 0 );
4140
4141 for (int j = 0; j < dPhi->at(0).size(); j++)
4142 {
4143 val = 0.0;
4144 for (int k = 0; k < dPhi->size(); k++)
4145 {
4146
4147 value1_j = dPhiTrans.at(k).at(j).at(0);
4148 value2_j = dPhiTrans.at(k).at(j).at(1);
4149
4150 value1_i = dPhiTrans.at(k).at(i).at(0);
4151 value2_i = dPhiTrans.at(k).at(i).at(1);
4152
4153 val = val + funcvalue * weightsDPhi->at(k) * ( value1_j*value1_i + value2_j*value2_i );
4154 }
4155 val = absDetB * val;
4156 value[0] = val;
4157
4158 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4159 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4160 indices[0] = glob_j;
4161
4162
4163 A->insertGlobalValues(glob_i, indices(), value());
4164 glob_j++;
4165 indices[0] = glob_j;
4166 A->insertGlobalValues(glob_i+1, indices(), value());
4167 }
4168 }
4169 }
4170 if (callFillComplete)
4171 {
4172 A->fillComplete();
4173 }
4174 }
4175 else if(dim == 3)
4176 {
4177 double val, value1_j, value2_j ,value3_j, value1_i, value2_i ,value3_i;
4178
4179 long long glob_i, glob_j;
4180 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
4181
4182 double distance1, distance2, distance3, distance4;
4183 vec_dbl_Type distance_mean(1); // Durchschnittliche Distanz des elements T
4184 for (int T = 0; T < elements->numberElements(); T++)
4185 {
4186 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4187 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4188 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4189 p4 = pointsRep->at(elements->getElement(T).getNode(3));
4190
4191 distance1 = dist->at(elements->getElement(T).getNode(0));
4192 distance2 = dist->at(elements->getElement(T).getNode(1));
4193 distance3 = dist->at(elements->getElement(T).getNode(2));
4194 distance4 = dist->at(elements->getElement(T).getNode(3));
4195
4196 distance_mean.at(0) = (distance1 + distance2 + distance3 + distance4)/4.0; //Mittelwert
4197 double funcvalue = func(&distance_mean.at(0),parameters);
4198
4199 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4200 detB = B.computeInverse(Binv);
4201 absDetB = std::fabs(detB);
4202
4203 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
4204 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4205 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4206
4207 for (int i = 0; i < dPhi->at(0).size(); i++)
4208 {
4209 Teuchos::Array<SC> value( 1, 0. );
4210 Teuchos::Array<GO> indices( 1, 0 );
4211
4212 for (int j = 0; j < dPhi->at(0).size(); j++)
4213 {
4214 val = 0.0;
4215 for (int k = 0; k < dPhi->size(); k++)
4216 {
4217 value1_j = dPhiTrans.at(k).at(j).at(0);
4218 value2_j = dPhiTrans.at(k).at(j).at(1);
4219 value3_j = dPhiTrans.at(k).at(j).at(2);
4220
4221 value1_i = dPhiTrans.at(k).at(i).at(0);
4222 value2_i = dPhiTrans.at(k).at(i).at(1);
4223 value3_i = dPhiTrans.at(k).at(i).at(2);
4224
4225 val = val + funcvalue * weightsDPhi->at(k) * (value1_j*value1_i + value2_j*value2_i + value3_j*value3_i);
4226 }
4227 val = absDetB * val;
4228 value[0] = val;
4229
4230 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4231 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4232 indices[0] = glob_j;
4233 A->insertGlobalValues(glob_i, indices(), value());
4234 glob_j++;
4235 indices[0] = glob_j;
4236 A->insertGlobalValues(glob_i+1, indices(), value());
4237 glob_j++;
4238 indices[0] = glob_j;
4239 A->insertGlobalValues(glob_i+2, indices(), value());
4240
4241 }
4242 }
4243 }
4244 if (callFillComplete)
4245 {
4246 A->fillComplete();
4247 }
4248 }
4249
4250}
4251
4252
4253
4254template <class SC, class LO, class GO, class NO>
4256 std::string FEType,
4257 MatrixPtr_Type &A,
4258 CoeffFunc_Type func,
4259 int* parameters,
4260 bool callFillComplete)
4261{
4262 // TODO: [JK] This function does the same as Natalie's stress assembly, just that she can also use a nonconstant viscosity. We should think about deprecating this function here.
4263 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
4264 int FEloc = this->checkFE(dim,FEType);
4265
4266 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4267 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4268 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4269
4270 vec3D_dbl_ptr_Type dPhi;
4271 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(new vec_dbl_Type(0));
4272 vec2D_dbl_ptr_Type quadPts;
4273
4274 // double value, value1_j, value2_j , value1_i, value2_i;
4275
4276 // inner( grad(u) + grad(u)^T , grad(v) ) has twice the polyonimial degree than grad(u) or grad(v).
4277 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv1);
4278 Helper::getDPhi(dPhi, weightsDPhi, dim, FEType, deg);
4279 Helper::getQuadratureValues(dim, deg, quadPts, weightsDPhi,FEType);
4280
4281 // SC = double, GO = long, UN = int
4282 SC detB;
4283 SC absDetB;
4284 SmallMatrix<SC> B(dim);
4285 SmallMatrix<SC> Binv(dim);
4286 GO glob_i, glob_j;
4287
4288 if (dim == 2)
4289 {
4290 double v11, v12, v21, v22, value1_j, value2_j , value1_i, value2_i;
4291 double e_11_j_1,e_12_j_1,e_21_j_1,e_22_j_1;
4292 double e_11_j_2,e_12_j_2,e_21_j_2,e_22_j_2;
4293 double e_11_i_1,e_12_i_1,e_21_i_1,e_22_i_1;
4294 double e_11_i_2,e_12_i_2,e_21_i_2,e_22_i_2;
4295
4296 SmallMatrix<double> tmpRes1(dim);
4297 SmallMatrix<double> tmpRes2(dim);
4298 SmallMatrix<double> e1i(dim);
4299 SmallMatrix<double> e2i(dim);
4300 SmallMatrix<double> e1j(dim);
4301 SmallMatrix<double> e2j(dim);
4302
4303 long long glob_i, glob_j;
4304 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
4305
4306 vec_dbl_Type xy(2);
4307 for (int T = 0; T < elements->numberElements(); T++)
4308 {
4309 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4310 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4311 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4312
4313 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
4314 detB = B.computeInverse(Binv);
4315 absDetB = std::fabs(detB);
4316
4317 // dPhiTrans sind die transformierten Basifunktionen, also B^(-T) * \grad_phi bzw. \grad_phi^T * B^(-1)
4318 // Also \hat{grad_phi}.
4319 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4320 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4321
4322 for (int i = 0; i < dPhi->at(0).size(); i++)
4323 {
4324 Teuchos::Array<SC> value11( 1, 0. );
4325 Teuchos::Array<SC> value12( 1, 0. );
4326 Teuchos::Array<SC> value21( 1, 0. );
4327 Teuchos::Array<SC> value22( 1, 0. );
4328 Teuchos::Array<GO> indices( 1, 0 );
4329
4330 for (int j=0; j < dPhi->at(0).size(); j++)
4331 {
4332 v11 = 0.0;v12 = 0.0;v21 = 0.0;v22 = 0.0;
4333 for (int k = 0; k < dPhi->size(); k++)
4334 {
4335 // Mappen der Gausspunkte (definiert auf T_ref) auf T (bzw. \Omega)
4336 // xy = F(quadPts) = B*quadPts + b, mit b = p1 (affin lineare Transformation)
4337 xy[0]=0.; xy[1]=0.;
4338 for (int r=0; r<2; r++) {
4339 xy[0] += B[0][r]*quadPts->at(k).at(r);
4340 xy[1] += B[1][r]*quadPts->at(k).at(r);
4341 }
4342 xy[0] += p1[0];
4343 xy[1] += p1[1];
4344
4345 value1_j = dPhiTrans.at(k).at(j).at(0);
4346 value2_j = dPhiTrans.at(k).at(j).at(1);
4347
4348 value1_i = dPhiTrans.at(k).at(i).at(0);
4349 value2_i = dPhiTrans.at(k).at(i).at(1);
4350
4351 tmpRes1[0][0] = value1_j;
4352 tmpRes1[0][1] = value2_j;
4353 tmpRes1[1][0] = 0.;
4354 tmpRes1[1][1] = 0.;
4355
4356 tmpRes2[0][0] = value1_j;
4357 tmpRes2[0][1] = 0.;
4358 tmpRes2[1][0] = value2_j;
4359 tmpRes2[1][1] = 0.;
4360
4361 tmpRes1.add(tmpRes2,e1j/*result*/);
4362
4363 e1i[0][0] = value1_i;
4364 e1i[0][1] = value2_i;
4365
4366
4367 tmpRes1[0][0] = 0.;
4368 tmpRes1[0][1] = 0.;
4369 tmpRes1[1][0] = value1_j;
4370 tmpRes1[1][1] = value2_j;
4371
4372 tmpRes2[0][0] = 0.;
4373 tmpRes2[0][1] = value1_j;
4374 tmpRes2[1][0] = 0.;
4375 tmpRes2[1][1] = value2_j;
4376
4377 tmpRes1.add(tmpRes2,e2j/*result*/);
4378
4379 e2i[1][0] = value1_i;
4380 e2i[1][1] = value2_i;
4381
4382 double funcvalue = func(&xy.at(0),parameters);
4383 v11 = v11 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e1j);
4384 v12 = v12 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e2j);
4385 v21 = v21 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e1j);
4386 v22 = v22 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e2j);
4387
4388 }
4389
4390 v11 = absDetB * v11;
4391 v12 = absDetB * v12;
4392 v21 = absDetB * v21;
4393 v22 = absDetB * v22;
4394
4395 value11[0] = v11;
4396 value12[0] = v12;
4397 value21[0] = v21;
4398 value22[0] = v22;
4399
4400 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4401 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4402 indices[0] = glob_j;
4403
4404 A->insertGlobalValues(glob_i, indices(), value11());
4405 A->insertGlobalValues(glob_i+1, indices(), value21());
4406 glob_j++;
4407 indices[0] = glob_j;
4408 A->insertGlobalValues(glob_i, indices(), value12());
4409 A->insertGlobalValues(glob_i+1, indices(), value22());
4410 }
4411 }
4412 }
4413 if (callFillComplete)
4414 {
4415 A->fillComplete();
4416 }
4417 }
4418 else if(dim == 3)
4419 {
4420 double v11, v12, v13, v21, v22, v23, v31, v32, v33, value1_j, value2_j, value3_j , value1_i, value2_i, value3_i;
4421
4422 SmallMatrix<double> e1i(dim);
4423 SmallMatrix<double> e2i(dim);
4424 SmallMatrix<double> e3i(dim);
4425 SmallMatrix<double> e1j(dim);
4426 SmallMatrix<double> e2j(dim);
4427 SmallMatrix<double> e3j(dim);
4428
4429 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
4430 vec_dbl_Type xyz(3);
4431
4432 for (int T = 0; T < elements->numberElements(); T++)
4433 {
4434 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4435 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4436 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4437 p4 = pointsRep->at(elements->getElement(T).getNode(3));
4438
4439 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4440 detB = B.computeInverse(Binv);
4441 absDetB = std::fabs(detB);
4442
4443 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
4444 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4445 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4446
4447 for (int i = 0; i < dPhi->at(0).size(); i++)
4448 {
4449 Teuchos::Array<SC> value11( 1, 0. );
4450 Teuchos::Array<SC> value12( 1, 0. );
4451 Teuchos::Array<SC> value13( 1, 0. );
4452 Teuchos::Array<SC> value21( 1, 0. );
4453 Teuchos::Array<SC> value22( 1, 0. );
4454 Teuchos::Array<SC> value23( 1, 0. );
4455 Teuchos::Array<SC> value31( 1, 0. );
4456 Teuchos::Array<SC> value32( 1, 0. );
4457 Teuchos::Array<SC> value33( 1, 0. );
4458 Teuchos::Array<GO> indices( 1, 0 );
4459
4460 for (int j = 0; j < dPhi->at(0).size(); j++)
4461 {
4462 v11 = 0.0;v12 = 0.0;v13 = 0.0;v21 = 0.0;v22 = 0.0;v23 = 0.0;v31 = 0.0;v32 = 0.0;v33 = 0.0;
4463 for (int k = 0; k < dPhi->size(); k++)
4464 {
4465
4466 xyz[0]=0.; xyz[1]=0.; xyz[2]=0.;
4467 for (int r = 0; r < 3; r++)
4468 {
4469 xyz[0] += B[0][r]*quadPts->at(k).at(r);
4470 xyz[1] += B[1][r]*quadPts->at(k).at(r);
4471 xyz[2] += B[2][r]*quadPts->at(k).at(r);
4472 }
4473 xyz[0] += p1[0];
4474 xyz[1] += p1[1];
4475 xyz[2] += p1[2];
4476
4477
4478
4479 value1_j = dPhiTrans.at(k).at(j).at(0);
4480 value2_j = dPhiTrans.at(k).at(j).at(1);
4481 value3_j = dPhiTrans.at(k).at(j).at(2);
4482
4483
4484 value1_i = dPhiTrans.at(k).at(i).at(0);
4485 value2_i = dPhiTrans.at(k).at(i).at(1);
4486 value3_i = dPhiTrans.at(k).at(i).at(2);
4487
4488
4489 e1j[0][0] = 2.*value1_j;
4490 e1j[0][1] = value2_j;
4491 e1j[0][2] = value3_j;
4492 e1j[1][0] = value2_j;
4493 e1j[2][0] = value3_j;
4494
4495 e1i[0][0] = value1_i;
4496 e1i[0][1] = value2_i;
4497 e1i[0][2] = value3_i;
4498
4499
4500 e2j[1][0] = value1_j;
4501 e2j[1][1] = 2.*value2_j;
4502 e2j[1][2] = value3_j;
4503 e2j[0][1] = value1_j;
4504 e2j[2][1] = value3_j;
4505
4506 e2i[1][0] = value1_i;
4507 e2i[1][1] = value2_i;
4508 e2i[1][2] = value3_i;
4509
4510
4511 e3j[2][0] = value1_j;
4512 e3j[2][1] = value2_j;
4513 e3j[2][2] = 2.*value3_j;
4514 e3j[0][2] = value1_j;
4515 e3j[1][2] = value2_j;
4516
4517 e3i[2][0] = value1_i;
4518 e3i[2][1] = value2_i;
4519 e3i[2][2] = value3_i;
4520
4521 double funcvalue = func(&xyz.at(0),parameters);
4522
4523 v11 = v11 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e1j);
4524 v12 = v12 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e2j);
4525 v13 = v13 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e3j);
4526
4527 v21 = v21 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e1j);
4528 v22 = v22 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e2j);
4529 v23 = v23 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e3j);
4530
4531 v31 = v31 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e1j);
4532 v32 = v32 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e2j);
4533 v33 = v33 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e3j);
4534
4535
4536 }
4537 v11 = absDetB * v11;
4538 v12 = absDetB * v12;
4539 v13 = absDetB * v13;
4540 v21 = absDetB * v21;
4541 v22 = absDetB * v22;
4542 v23 = absDetB * v23;
4543 v31 = absDetB * v31;
4544 v32 = absDetB * v32;
4545 v33 = absDetB * v33;
4546
4547 value11[0] = v11;
4548 value12[0] = v12;
4549 value13[0] = v13;
4550 value21[0] = v21;
4551 value22[0] = v22;
4552 value23[0] = v23;
4553 value31[0] = v31;
4554 value32[0] = v32;
4555 value33[0] = v33;
4556
4557 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4558 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4559 indices[0] = glob_j;
4560 A->insertGlobalValues(glob_i, indices(), value11());
4561 A->insertGlobalValues(glob_i+1, indices(), value21());
4562 A->insertGlobalValues(glob_i+2, indices(), value31());
4563
4564 glob_j++;
4565 indices[0] = glob_j;
4566 A->insertGlobalValues(glob_i, indices(), value12());
4567 A->insertGlobalValues(glob_i+1, indices(), value22());
4568 A->insertGlobalValues(glob_i+2, indices(), value32());
4569
4570 glob_j++;
4571 indices[0] = glob_j;
4572 A->insertGlobalValues(glob_i, indices(), value13());
4573 A->insertGlobalValues(glob_i+1, indices(), value23());
4574 A->insertGlobalValues(glob_i+2, indices(), value33());
4575 }
4576 }
4577 }
4578 if (callFillComplete)
4579 {
4580 A->fillComplete();
4581 }
4582 }
4583
4584}
4585
4586
4587
4588template <class SC, class LO, class GO, class NO>
4590 std::string FEType,
4591 MatrixPtr_Type &A,
4592 double lambda,
4593 double mu,
4594 bool callFillComplete)
4595{
4596 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
4597 int FEloc = this->checkFE(dim,FEType);
4598
4599 // Hole Elemente und Knotenliste
4600 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4601 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4602 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4603
4604 vec3D_dbl_ptr_Type dPhi;
4605 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(new vec_dbl_Type(0));
4606 vec2D_dbl_ptr_Type quadPts;
4607
4608 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv1);
4609
4610 // Hole die grad_phi, hier DPhi
4611 Helper::getDPhi(dPhi, weightsDPhi, dim, FEType, deg);
4612 Helper::getQuadratureValues(dim, deg, quadPts, weightsDPhi,FEType);
4613
4614 // Definiere die Basisfunktion \phi_i bzw. \phi_j
4615 // vec_dbl_Type basisValues_i(dim,0.), basisValues_j(dim,0.);
4616
4617 // SC = double, GO = long, UN = int
4618 SC detB;
4619 SC absDetB;
4620 SmallMatrix<SC> B(dim);
4621 SmallMatrix<SC> Binv(dim);
4622 GO glob_i, glob_j;
4623
4624 // Fuer Zwischenergebniss
4625 SC res;
4626
4627 // Fuer die Berechnung der Spur
4628 double res_trace_i, res_trace_j;
4629
4630 if (dim == 2)
4631 {
4632
4633 double v11, v12, v21, v22;
4634 // Setzte Vektoren der Groesse 2 und initialisiere mit 0.0 (double)
4635 vec_dbl_Type p1(2,0.0), p2(2,0.0), p3(2,0.0);
4636
4637 // Matrizen der Groesse (2x2) in denen die einzelnen Epsilon-Tensoren berechnet werden.
4638 // Siehe unten fuer mehr.
4639 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim),
4640 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim);
4641
4642 for (int T = 0; T < elements->numberElements(); T++)
4643 {
4644 // Hole die Eckknoten des Dreiecks
4645 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4646 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4647 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4648
4649 // Berechne die Transormationsmatrix B fuer das jeweilige Element (2D)
4650 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4651 detB = B.computeInverse(Binv);
4652 absDetB = std::fabs(detB);
4653
4654 // dPhiTrans sind die transformierten Basifunktionen, also B^(-T) * \grad_phi bzw. \grad_phi^T * B^(-1).
4655 // Also \hat{grad_phi}.
4656 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4657 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4658
4659 for (int i = 0; i < dPhi->at(0).size(); i++)
4660 {
4661 Teuchos::Array<SC> value11( 1, 0. );
4662 Teuchos::Array<SC> value12( 1, 0. );
4663 Teuchos::Array<SC> value21( 1, 0. );
4664 Teuchos::Array<SC> value22( 1, 0. );
4665 Teuchos::Array<GO> indices( 1, 0 );
4666
4667 for (int j = 0; j < dPhi->at(0).size(); j++)
4668 {
4669 v11 = 0.0; v12 = 0.0; v21 = 0.0; v22 = 0.0;
4670 for (int k = 0; k < dPhi->size(); k++)
4671 {
4672 // In epsilonValuesMat1_i (2x2 Matrix) steht fuer die Ansatzfunktion i bzw. \phi_i
4673 // der epsilonTensor fuer eine skalare Ansatzfunktion fuer die Richtung 1 (vgl. Mat1).
4674 // Also in Mat1_i wird dann also phi_i = (phi_scalar_i, 0) gesetzt und davon \eps berechnet.
4675
4676 // Stelle \hat{grad_phi_i} = basisValues_i auf, also B^(-T)*grad_phi_i
4677 // GradPhiOnRef( dPhi->at(k).at(i), b_T_inv, basisValues_i );
4678
4679 // \eps(v) = \eps(phi_i)
4680 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0); // x-Richtung
4681 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1); // y-Richtung
4682
4683 // Siehe oben, nur fuer j
4684 // GradPhiOnRef( DPhi->at(k).at(j), b_T_inv, basisValues_j );
4685
4686 // \eps(u) = \eps(phi_j)
4687 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0); // x-Richtung
4688 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1); // y-Richtung
4689
4690 // Nun berechnen wir \eps(u):\eps(v) = \eps(phi_j):\eps(phi_i).
4691 // Das Ergebniss steht in res.
4692 // Berechne zudem noch die Spur der Epsilon-Tensoren tr(\eps(u)) (j) und tr(\eps(v)) (i)
4693 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res); // x-x
4694 epsilonValuesMat1_i.trace(res_trace_i);
4695 epsilonValuesMat1_j.trace(res_trace_j);
4696 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4697
4698 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res); // x-y
4699 epsilonValuesMat1_i.trace(res_trace_i);
4700 epsilonValuesMat2_j.trace(res_trace_j);
4701 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4702
4703 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res); // y-x
4704 epsilonValuesMat2_i.trace(res_trace_i);
4705 epsilonValuesMat1_j.trace(res_trace_j);
4706 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4707
4708 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res); // y-y
4709 epsilonValuesMat2_i.trace(res_trace_i);
4710 epsilonValuesMat2_j.trace(res_trace_j);
4711 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4712
4713
4714 }
4715 // Noch mit der abs(det(B)) skalieren
4716 v11 = absDetB * v11;
4717 v12 = absDetB * v12;
4718 v21 = absDetB * v21;
4719 v22 = absDetB * v22;
4720
4721 value11[0] = v11;
4722 value12[0] = v12;
4723 value21[0] = v21;
4724 value22[0] = v22;
4725
4726 // Hole die globale Zeile und Spalte in der die Eintraege hingeschrieben werden sollen
4727 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4728 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4729 indices[0] = glob_j;
4730 A->insertGlobalValues(glob_i, indices(), value11()); // x-x
4731 A->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
4732 glob_j++;
4733 indices[0] = glob_j;
4734 A->insertGlobalValues(glob_i, indices(), value12()); // x-y
4735 A->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
4736 }
4737 }
4738 }
4739 if (callFillComplete)
4740 {
4741 A->fillComplete();
4742 }
4743 }
4744 else if(dim == 3)
4745 {
4746
4747 double v11, v12, v13, v21, v22, v23, v31, v32, v33;
4748
4749 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
4750 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim), epsilonValuesMat3_i(dim),
4751 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim), epsilonValuesMat3_j(dim);
4752
4753 for (int T = 0; T < elements->numberElements(); T++)
4754 {
4755 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4756 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4757 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4758 p4 = pointsRep->at(elements->getElement(T).getNode(3));
4759
4760 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
4761 detB = B.computeInverse(Binv);
4762 absDetB = std::fabs(detB);
4763
4764 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
4765 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4766 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
4767
4768 for (int i = 0; i < dPhi->at(0).size(); i++)
4769 {
4770 Teuchos::Array<SC> value11( 1, 0. );
4771 Teuchos::Array<SC> value12( 1, 0. );
4772 Teuchos::Array<SC> value13( 1, 0. );
4773 Teuchos::Array<SC> value21( 1, 0. );
4774 Teuchos::Array<SC> value22( 1, 0. );
4775 Teuchos::Array<SC> value23( 1, 0. );
4776 Teuchos::Array<SC> value31( 1, 0. );
4777 Teuchos::Array<SC> value32( 1, 0. );
4778 Teuchos::Array<SC> value33( 1, 0. );
4779 Teuchos::Array<GO> indices( 1, 0 );
4780
4781 for (int j = 0; j < dPhi->at(0).size(); j++)
4782 {
4783 v11 = 0.0; v12 = 0.0; v13 = 0.0; v21 = 0.0; v22 = 0.0; v23 = 0.0; v31 = 0.0; v32 = 0.0; v33 = 0.0;
4784 for (int k = 0; k < dPhi->size(); k++)
4785 {
4786
4787 // GradPhiOnRef( DPhi->at(k).at(i), b_T_inv, basisValues_i );
4788
4789 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0); // x-Richtung
4790 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1); // y-Richtung
4791 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat3_i, 2); // z-Richtung
4792
4793
4794 // GradPhiOnRef( DPhi->at(k).at(j), b_T_inv, basisValues_j );
4795
4796 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0); // x-Richtung
4797 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1); // y-Richtung
4798 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat3_j, 2); // z-Richtung
4799
4800 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res); // x-x
4801 epsilonValuesMat1_i.trace(res_trace_i);
4802 epsilonValuesMat1_j.trace(res_trace_j);
4803 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4804
4805 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res); // x-y
4806 epsilonValuesMat1_i.trace(res_trace_i);
4807 epsilonValuesMat2_j.trace(res_trace_j);
4808 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4809
4810 epsilonValuesMat1_i.innerProduct(epsilonValuesMat3_j, res); // x-z
4811 epsilonValuesMat1_i.trace(res_trace_i);
4812 epsilonValuesMat3_j.trace(res_trace_j);
4813 v13 = v13 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4814
4815 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res); // y-x
4816 epsilonValuesMat2_i.trace(res_trace_i);
4817 epsilonValuesMat1_j.trace(res_trace_j);
4818 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4819
4820 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res); // y-y
4821 epsilonValuesMat2_i.trace(res_trace_i);
4822 epsilonValuesMat2_j.trace(res_trace_j);
4823 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4824
4825 epsilonValuesMat2_i.innerProduct(epsilonValuesMat3_j, res); // y-z
4826 epsilonValuesMat2_i.trace(res_trace_i);
4827 epsilonValuesMat3_j.trace(res_trace_j);
4828 v23 = v23 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4829
4830 epsilonValuesMat3_i.innerProduct(epsilonValuesMat1_j, res); // z-x
4831 epsilonValuesMat3_i.trace(res_trace_i);
4832 epsilonValuesMat1_j.trace(res_trace_j);
4833 v31 = v31 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4834
4835 epsilonValuesMat3_i.innerProduct(epsilonValuesMat2_j, res); // z-y
4836 epsilonValuesMat3_i.trace(res_trace_i);
4837 epsilonValuesMat2_j.trace(res_trace_j);
4838 v32 = v32 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4839
4840 epsilonValuesMat3_i.innerProduct(epsilonValuesMat3_j, res); // z-z
4841 epsilonValuesMat3_i.trace(res_trace_i);
4842 epsilonValuesMat3_j.trace(res_trace_j);
4843 v33 = v33 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
4844
4845 }
4846 v11 = absDetB * v11;
4847 v12 = absDetB * v12;
4848 v13 = absDetB * v13;
4849 v21 = absDetB * v21;
4850 v22 = absDetB * v22;
4851 v23 = absDetB * v23;
4852 v31 = absDetB * v31;
4853 v32 = absDetB * v32;
4854 v33 = absDetB * v33;
4855
4856 value11[0] = v11;
4857 value12[0] = v12;
4858 value13[0] = v13;
4859 value21[0] = v21;
4860 value22[0] = v22;
4861 value23[0] = v23;
4862 value31[0] = v31;
4863 value32[0] = v32;
4864 value33[0] = v33;
4865
4866 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4867 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4868 indices[0] = glob_j;
4869 A->insertGlobalValues(glob_i, indices(), value11()); // x-x
4870 A->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
4871 A->insertGlobalValues(glob_i+2, indices(), value31()); // z-x
4872 glob_j++;
4873 indices[0] = glob_j;
4874 A->insertGlobalValues(glob_i, indices(), value12()); // x-y
4875 A->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
4876 A->insertGlobalValues(glob_i+2, indices(), value32()); // z-y
4877 glob_j++;
4878 indices[0] = glob_j;
4879 A->insertGlobalValues(glob_i, indices(), value13()); // x-z
4880 A->insertGlobalValues(glob_i+1, indices(), value23()); // y-z
4881 A->insertGlobalValues(glob_i+2, indices(), value33()); // z-z
4882 }
4883 }
4884 }
4885 if (callFillComplete)
4886 {
4887 A->fillComplete();
4888 }
4889 }
4890}
4891
4892// Determine the change of emodule depending on concentration
4893template <class SC, class LO, class GO, class NO>
4894void FE<SC,LO,GO,NO>::determineEMod(std::string FEType, MultiVectorPtr_Type solution,MultiVectorPtr_Type &eModVec, DomainConstPtr_Type domain, ParameterListPtr_Type params){
4895
4896
4897 ElementsPtr_Type elements = domain->getElementsC();
4898
4899 int dim = domain->getDimension();
4900 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
4901
4902 //MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4903
4904 Teuchos::ArrayRCP< const SC > uArray = solution->getData(0);
4905 Teuchos::ArrayRCP< SC > eModVecA = eModVec->getDataNonConst(0);
4906
4907 double E0 = params->sublist("Parameter Solid").get("E",3.0e+6);
4908 double E1 = params->sublist("Parameter Solid").get("E1",3.0e+5);
4909 double c1 = params->sublist("Parameter Solid").get("c1",1.0);
4910 double eModMax =E1;
4911 double eModMin = E0;
4912
4913 int nodesElement = elements->getElement(0).getVectorNodeList().size();
4914 for (UN T=0; T<elements->numberElements(); T++) {
4915
4916 /*buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
4917 detB = B.computeInverse(Binv);
4918 absDetB = std::fabs(detB);*/
4919
4920 double uLoc = 0.;
4921
4922 for(int i=0; i< nodesElement;i++){
4923 LO index = elements->getElement(T).getNode(i) ;
4924 uLoc += 1./nodesElement*uArray[index];
4925 }
4926
4927 eModVecA[T] = E0-(E0-E1)*(uLoc/(uLoc+c1));
4928 if(eModVecA[T] > eModMax )
4929 eModMax = eModVecA[T];
4930 if(eModVecA[T] < eModMin)
4931 eModMin = eModVecA[T];
4932 }
4933 Teuchos::reduceAll<int, double> (*(domain->getComm()), Teuchos::REDUCE_MIN, eModMin, Teuchos::outArg (eModMin));
4934 Teuchos::reduceAll<int, double> (*(domain->getComm()), Teuchos::REDUCE_MAX, eModMax, Teuchos::outArg (eModMax));
4935
4936 if(domain->getComm()->getRank()==0)
4937 std::cout << " ################# eMOD Min: " << eModMin << " \t eModMax: " << eModMax<< " ############# " << std::endl;
4938
4939
4940}
4941
4942
4944template <class SC, class LO, class GO, class NO>
4946 std::string FEType,
4947 MatrixPtr_Type &A,
4948 MultiVectorPtr_Type eModVec,
4949 double nu,
4950 bool callFillComplete)
4951{
4952 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
4953 int FEloc = this->checkFE(dim,FEType);
4954 // Hole Elemente und Knotenliste
4955 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4956 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4957 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4958
4959 vec3D_dbl_ptr_Type dPhi;
4960 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(new vec_dbl_Type(0));
4961 vec2D_dbl_ptr_Type quadPts;
4962
4963 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv1);
4964
4965 // Hole die grad_phi, hier DPhi
4966 Helper::getDPhi(dPhi, weightsDPhi, dim, FEType, deg);
4967 Helper::getQuadratureValues(dim, deg, quadPts, weightsDPhi,FEType);
4968
4969 SC detB;
4970 SC absDetB;
4971 SmallMatrix<SC> B(dim);
4972 SmallMatrix<SC> Binv(dim);
4973 GO glob_i, glob_j;
4974
4975 // Fuer Zwischenergebniss
4976 SC res;
4977
4978 // Fuer die Berechnung der Spur
4979 double res_trace_i, res_trace_j;
4980
4981 Teuchos::ArrayRCP< const SC > E = eModVec->getData(0);
4982 double lambda;
4983 double mu ;
4984
4985 if (dim == 2)
4986 {
4987
4988 double v11, v12, v21, v22;
4989 // Setzte Vektoren der Groesse 2 und initialisiere mit 0.0 (double)
4990 vec_dbl_Type p1(2,0.0), p2(2,0.0), p3(2,0.0);
4991
4992 // Matrizen der Groesse (2x2) in denen die einzelnen Epsilon-Tensoren berechnet werden.
4993 // Siehe unten fuer mehr.
4994 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim),
4995 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim);
4996
4997 for (int T = 0; T < elements->numberElements(); T++)
4998 {
5000 lambda = E[T]* nu / ((1.+nu)*(1.-2.*nu));
5001 mu = E[T] / (2.*(1.+nu));
5002
5003 // Hole die Eckknoten des Dreiecks
5004 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5005 p2 = pointsRep->at(elements->getElement(T).getNode(1));
5006 p3 = pointsRep->at(elements->getElement(T).getNode(2));
5007
5008 // Berechne die Transormationsmatrix B fuer das jeweilige Element (2D)
5009 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
5010 detB = B.computeInverse(Binv);
5011 absDetB = std::fabs(detB);
5012
5013 // dPhiTrans sind die transformierten Basifunktionen, also B^(-T) * \grad_phi bzw. \grad_phi^T * B^(-1).
5014 // Also \hat{grad_phi}.
5015 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
5016 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
5017
5018 for (int i = 0; i < dPhi->at(0).size(); i++)
5019 {
5020 Teuchos::Array<SC> value11( 1, 0. );
5021 Teuchos::Array<SC> value12( 1, 0. );
5022 Teuchos::Array<SC> value21( 1, 0. );
5023 Teuchos::Array<SC> value22( 1, 0. );
5024 Teuchos::Array<GO> indices( 1, 0 );
5025
5026 for (int j = 0; j < dPhi->at(0).size(); j++)
5027 {
5028 v11 = 0.0; v12 = 0.0; v21 = 0.0; v22 = 0.0;
5029 for (int k = 0; k < dPhi->size(); k++)
5030 {
5031 // In epsilonValuesMat1_i (2x2 Matrix) steht fuer die Ansatzfunktion i bzw. \phi_i
5032 // der epsilonTensor fuer eine skalare Ansatzfunktion fuer die Richtung 1 (vgl. Mat1).
5033 // Also in Mat1_i wird dann also phi_i = (phi_scalar_i, 0) gesetzt und davon \eps berechnet.
5034
5035 // Stelle \hat{grad_phi_i} = basisValues_i auf, also B^(-T)*grad_phi_i
5036 // GradPhiOnRef( dPhi->at(k).at(i), b_T_inv, basisValues_i );
5037
5038 // \eps(v) = \eps(phi_i)
5039 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0); // x-Richtung
5040 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1); // y-Richtung
5041
5042 // Siehe oben, nur fuer j
5043 // GradPhiOnRef( DPhi->at(k).at(j), b_T_inv, basisValues_j );
5044
5045 // \eps(u) = \eps(phi_j)
5046 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0); // x-Richtung
5047 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1); // y-Richtung
5048
5049 // Nun berechnen wir \eps(u):\eps(v) = \eps(phi_j):\eps(phi_i).
5050 // Das Ergebniss steht in res.
5051 // Berechne zudem noch die Spur der Epsilon-Tensoren tr(\eps(u)) (j) und tr(\eps(v)) (i)
5052 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res); // x-x
5053 epsilonValuesMat1_i.trace(res_trace_i);
5054 epsilonValuesMat1_j.trace(res_trace_j);
5055 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5056
5057 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res); // x-y
5058 epsilonValuesMat1_i.trace(res_trace_i);
5059 epsilonValuesMat2_j.trace(res_trace_j);
5060 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5061
5062 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res); // y-x
5063 epsilonValuesMat2_i.trace(res_trace_i);
5064 epsilonValuesMat1_j.trace(res_trace_j);
5065 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5066
5067 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res); // y-y
5068 epsilonValuesMat2_i.trace(res_trace_i);
5069 epsilonValuesMat2_j.trace(res_trace_j);
5070 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5071
5072
5073 }
5074 // Noch mit der abs(det(B)) skalieren
5075 v11 = absDetB * v11;
5076 v12 = absDetB * v12;
5077 v21 = absDetB * v21;
5078 v22 = absDetB * v22;
5079
5080 value11[0] = v11;
5081 value12[0] = v12;
5082 value21[0] = v21;
5083 value22[0] = v22;
5084
5085 // Hole die globale Zeile und Spalte in der die Eintraege hingeschrieben werden sollen
5086 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
5087 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
5088 indices[0] = glob_j;
5089 A->insertGlobalValues(glob_i, indices(), value11()); // x-x
5090 A->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
5091 glob_j++;
5092 indices[0] = glob_j;
5093 A->insertGlobalValues(glob_i, indices(), value12()); // x-y
5094 A->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
5095 }
5096 }
5097 }
5098 if (callFillComplete)
5099 {
5100 A->fillComplete();
5101 }
5102 }
5103 else if(dim == 3)
5104 {
5105
5106 double v11, v12, v13, v21, v22, v23, v31, v32, v33;
5107
5108 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
5109 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim), epsilonValuesMat3_i(dim),
5110 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim), epsilonValuesMat3_j(dim);
5111
5112 for (int T = 0; T < elements->numberElements(); T++)
5113 {
5114 lambda = E[T]* nu / ((1.+nu)*(1.-2.*nu));
5115 mu = E[T] / (2.*(1.+nu));
5116
5117 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5118 p2 = pointsRep->at(elements->getElement(T).getNode(1));
5119 p3 = pointsRep->at(elements->getElement(T).getNode(2));
5120 p4 = pointsRep->at(elements->getElement(T).getNode(3));
5121
5122 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
5123 detB = B.computeInverse(Binv);
5124 absDetB = std::fabs(detB);
5125
5126 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
5127 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
5128 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
5129
5130 for (int i = 0; i < dPhi->at(0).size(); i++)
5131 {
5132
5133 Teuchos::Array<SC> value11( 1, 0. );
5134 Teuchos::Array<SC> value12( 1, 0. );
5135 Teuchos::Array<SC> value13( 1, 0. );
5136 Teuchos::Array<SC> value21( 1, 0. );
5137 Teuchos::Array<SC> value22( 1, 0. );
5138 Teuchos::Array<SC> value23( 1, 0. );
5139 Teuchos::Array<SC> value31( 1, 0. );
5140 Teuchos::Array<SC> value32( 1, 0. );
5141 Teuchos::Array<SC> value33( 1, 0. );
5142 Teuchos::Array<GO> indices( 1, 0 );
5143
5144 for (int j = 0; j < dPhi->at(0).size(); j++)
5145 {
5146 v11 = 0.0; v12 = 0.0; v13 = 0.0; v21 = 0.0; v22 = 0.0; v23 = 0.0; v31 = 0.0; v32 = 0.0; v33 = 0.0;
5147 for (int k = 0; k < dPhi->size(); k++)
5148 {
5149
5150 // GradPhiOnRef( DPhi->at(k).at(i), b_T_inv, basisValues_i );
5151
5152 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0); // x-Richtung
5153 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1); // y-Richtung
5154 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat3_i, 2); // z-Richtung
5155
5156
5157 // GradPhiOnRef( DPhi->at(k).at(j), b_T_inv, basisValues_j );
5158
5159 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0); // x-Richtung
5160 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1); // y-Richtung
5161 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat3_j, 2); // z-Richtung
5162
5163 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res); // x-x
5164 epsilonValuesMat1_i.trace(res_trace_i);
5165 epsilonValuesMat1_j.trace(res_trace_j);
5166 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5167
5168 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res); // x-y
5169 epsilonValuesMat1_i.trace(res_trace_i);
5170 epsilonValuesMat2_j.trace(res_trace_j);
5171 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5172
5173 epsilonValuesMat1_i.innerProduct(epsilonValuesMat3_j, res); // x-z
5174 epsilonValuesMat1_i.trace(res_trace_i);
5175 epsilonValuesMat3_j.trace(res_trace_j);
5176 v13 = v13 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5177
5178 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res); // y-x
5179 epsilonValuesMat2_i.trace(res_trace_i);
5180 epsilonValuesMat1_j.trace(res_trace_j);
5181 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5182
5183 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res); // y-y
5184 epsilonValuesMat2_i.trace(res_trace_i);
5185 epsilonValuesMat2_j.trace(res_trace_j);
5186 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5187
5188 epsilonValuesMat2_i.innerProduct(epsilonValuesMat3_j, res); // y-z
5189 epsilonValuesMat2_i.trace(res_trace_i);
5190 epsilonValuesMat3_j.trace(res_trace_j);
5191 v23 = v23 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5192
5193 epsilonValuesMat3_i.innerProduct(epsilonValuesMat1_j, res); // z-x
5194 epsilonValuesMat3_i.trace(res_trace_i);
5195 epsilonValuesMat1_j.trace(res_trace_j);
5196 v31 = v31 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5197
5198 epsilonValuesMat3_i.innerProduct(epsilonValuesMat2_j, res); // z-y
5199 epsilonValuesMat3_i.trace(res_trace_i);
5200 epsilonValuesMat2_j.trace(res_trace_j);
5201 v32 = v32 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5202
5203 epsilonValuesMat3_i.innerProduct(epsilonValuesMat3_j, res); // z-z
5204 epsilonValuesMat3_i.trace(res_trace_i);
5205 epsilonValuesMat3_j.trace(res_trace_j);
5206 v33 = v33 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
5207
5208 }
5209 v11 = absDetB * v11;
5210 v12 = absDetB * v12;
5211 v13 = absDetB * v13;
5212 v21 = absDetB * v21;
5213 v22 = absDetB * v22;
5214 v23 = absDetB * v23;
5215 v31 = absDetB * v31;
5216 v32 = absDetB * v32;
5217 v33 = absDetB * v33;
5218
5219 value11[0] = v11;
5220 value12[0] = v12;
5221 value13[0] = v13;
5222 value21[0] = v21;
5223 value22[0] = v22;
5224 value23[0] = v23;
5225 value31[0] = v31;
5226 value32[0] = v32;
5227 value33[0] = v33;
5228
5229 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
5230 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
5231 indices[0] = glob_j;
5232 A->insertGlobalValues(glob_i, indices(), value11()); // x-x
5233 A->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
5234 A->insertGlobalValues(glob_i+2, indices(), value31()); // z-x
5235 glob_j++;
5236 indices[0] = glob_j;
5237 A->insertGlobalValues(glob_i, indices(), value12()); // x-y
5238 A->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
5239 A->insertGlobalValues(glob_i+2, indices(), value32()); // z-y
5240 glob_j++;
5241 indices[0] = glob_j;
5242 A->insertGlobalValues(glob_i, indices(), value13()); // x-z
5243 A->insertGlobalValues(glob_i+1, indices(), value23()); // y-z
5244 A->insertGlobalValues(glob_i+2, indices(), value33()); // z-z
5245 }
5246 }
5247 }
5248 if (callFillComplete)
5249 {
5250 A->fillComplete();
5251 }
5252 }
5253}
5254
5256template <class SC, class LO, class GO, class NO>
5258 std::string FEType,
5259 MatrixPtr_Type &A,
5260 MultiVectorPtr_Type w,
5261 bool callFillComplete)
5262{
5263
5264 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
5265 int FEloc = this->checkFE(dim,FEType);
5266
5267 DomainConstPtr_Type domain = domainVec_.at(FEloc);
5268 ElementsPtr_Type elements = domain->getElementsC();
5269 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
5270 MapConstPtr_Type map = domain->getMapRepeated();
5271
5272 vec3D_dbl_ptr_Type dPhi;
5273 vec2D_dbl_ptr_Type phi;
5274 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
5275 vec2D_dbl_ptr_Type quadPts;
5276
5277 UN extraDeg = Helper::determineDegree( dim, FEType, Helper::Deriv1); // Fuer diskretes (\grad \cdot w) in den Gausspuntken
5278 UN deg = 2*Helper::determineDegree( dim, FEType, Helper::Deriv0) + extraDeg;
5279
5280 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
5281 Helper::getPhi(phi, weights, dim, FEType, deg);
5282 Helper::getQuadratureValues(dim, deg, quadPts, weights,FEType);
5283
5284 // SC = double, GO = long, UN = int
5285 SC detB;
5286 SC absDetB;
5287 SmallMatrix<SC> B(dim);
5288 SmallMatrix<SC> Binv(dim);
5289 GO glob_i, glob_j;
5290
5291 // Der nichtlineare Teil als Array
5292 Teuchos::ArrayRCP< const SC > wArray = w->getData(0);
5293
5294 if (dim == 2)
5295 {
5296 double val;
5297 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
5298
5299 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.)); // diskretes w_11. Siehe unten.
5300 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
5301 vec2D_dbl_Type divergenz(1, vec_dbl_Type(weights->size(), -1.));
5302
5303 for (int T = 0; T < elements->numberElements(); T++)
5304 {
5305 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5306 p2 = pointsRep->at(elements->getElement(T).getNode(1));
5307 p3 = pointsRep->at(elements->getElement(T).getNode(2));
5308
5309 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
5310 detB = B.computeInverse(Binv);
5311 absDetB = std::fabs(detB);
5312
5313 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
5314 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
5315 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
5316
5317 // Diskretes \div(w) = (\grad \cdot w) = w_11 + w_22 berechnen,
5318 // wobei w_ij = \frac{\partial w_i}{\partial x_j} ist.
5319 for(int k = 0; k < dPhiTrans.size(); k++) // Quadraturpunkte
5320 {
5321 w11[0][k] = 0.0;
5322 w22[0][k] = 0.0;
5323 for(int i = 0; i < dPhiTrans[0].size(); i++)
5324 {
5325 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
5326 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
5327 w11[0][k] += wArray[index1] * dPhiTrans[k][i][0];
5328 w22[0][k] += wArray[index2] * dPhiTrans[k][i][1];
5329
5330 // TEST
5331 // LO indexTest1 = dim * i + 0;
5332 // LO indexTest2 = dim * i + 1;
5333 // w11[0][k] += wTest[indexTest1] * dPhiTrans[k][i][0];
5334 // w22[0][k] += wTest[indexTest2] * dPhiTrans[k][i][1];
5335 }
5336 }
5337
5338 for(int k = 0; k < dPhiTrans.size(); k++) // Quadraturpunkte
5339 {
5340 divergenz[0][k] = w11[0][k] + w22[0][k];
5341 // if(T == 0)
5342 // {
5343 // std::cout << "k: " << k << " Divergenz: " << divergenz[0][k] << '\n';
5344 // }
5345 }
5346
5347
5348 for (int i = 0; i < dPhi->at(0).size(); i++)
5349 {
5350 Teuchos::Array<SC> value( 1, 0. );
5351 Teuchos::Array<GO> indices( 1, 0 );
5352
5353 for (int j = 0; j < dPhi->at(0).size(); j++)
5354 {
5355 val = 0.0;
5356 for (int k = 0; k < dPhi->size(); k++)
5357 {
5358 val = val + divergenz[0][k] * weights->at(k) * (*phi)[k][i] * (*phi)[k][j];
5359 }
5360 val = absDetB * val;
5361 value[0] = val;
5362
5363 // if(T == 0)
5364 // {
5365 // std::cout << "i: " << i << " j: " << j << " val: " << val << '\n';
5366 // }
5367
5368 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
5369 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
5370 indices[0] = glob_j;
5371
5372 A->insertGlobalValues(glob_i, indices(), value());
5373 glob_j++;
5374 indices[0] = glob_j;
5375 A->insertGlobalValues(glob_i+1, indices(), value());
5376 }
5377 }
5378 }
5379 if (callFillComplete)
5380 {
5381 A->fillComplete();
5382 }
5383 }
5384 else if(dim == 3)
5385 {
5386 double val;
5387
5388 // long long glob_i, glob_j;
5389 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
5390
5391 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.)); // diskretes w_11. Siehe unten.
5392 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
5393 vec2D_dbl_Type w33(1, vec_dbl_Type(weights->size(), -1.));
5394 vec2D_dbl_Type divergenz(1, vec_dbl_Type(weights->size(), -1.));
5395
5396 for (int T = 0; T < elements->numberElements(); T++)
5397 {
5398 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5399 p2 = pointsRep->at(elements->getElement(T).getNode(1));
5400 p3 = pointsRep->at(elements->getElement(T).getNode(2));
5401 p4 = pointsRep->at(elements->getElement(T).getNode(3));
5402
5403 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
5404 detB = B.computeInverse(Binv);
5405 absDetB = std::fabs(detB);
5406
5407 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
5408 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
5409 applyBTinv( dPhi, dPhiTrans, Binv ); //dPhiTrans berechnen
5410
5411 // Diskretes \div(w) = (\grad \cdot w) = w_11 + w_22 + w33 berechnen,
5412 // wobei w_ij = \frac{\partial w_i}{\partial x_j} ist.
5413 for(int k = 0; k < dPhiTrans.size(); k++) // Quadraturpunkte
5414 {
5415 w11[0][k] = 0.0;
5416 w22[0][k] = 0.0;
5417 w33[0][k] = 0.0;
5418 for(int i = 0; i < dPhiTrans[0].size(); i++)
5419 {
5420 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
5421 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
5422 LO index3 = dim * elements->getElement(T).getNode(i) + 2; // z
5423 w11[0][k] += wArray[index1] * dPhiTrans[k][i][0];
5424 w22[0][k] += wArray[index2] * dPhiTrans[k][i][1];
5425 w33[0][k] += wArray[index3] * dPhiTrans[k][i][2];
5426 }
5427 }
5428
5429 for(int k = 0; k < dPhiTrans.size(); k++) // Quadraturpunkte
5430 {
5431 divergenz[0][k] = w11[0][k] + w22[0][k] + w33[0][k];
5432 }
5433
5434 for (int i = 0; i < dPhi->at(0).size(); i++)
5435 {
5436 Teuchos::Array<SC> value( 1, 0. );
5437 Teuchos::Array<GO> indices( 1, 0 );
5438
5439 for (int j = 0; j < dPhi->at(0).size(); j++)
5440 {
5441 val = 0.0;
5442 for (int k = 0; k < dPhi->size(); k++)
5443 {
5444 val = val + divergenz[0][k] * weights->at(k) * (*phi)[k][i] * (*phi)[k][j];
5445 }
5446 val = absDetB * val;
5447 value[0] = val;
5448
5449 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
5450 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
5451 indices[0] = glob_j;
5452 A->insertGlobalValues(glob_i, indices(), value());
5453 glob_j++;
5454 indices[0] = glob_j;
5455 A->insertGlobalValues(glob_i+1, indices(), value());
5456 glob_j++;
5457 indices[0] = glob_j;
5458 A->insertGlobalValues(glob_i+2, indices(), value());
5459
5460 }
5461 }
5462 }
5463 if (callFillComplete)
5464 {
5465 A->fillComplete();
5466 }
5467 }
5468}
5469
5470template <class SC, class LO, class GO, class NO>
5471void FE<SC,LO,GO,NO>::assemblyDummyCoupling(int dim,
5472 std::string FEType,
5473 MatrixPtr_Type &C,
5474 int FEloc, // 0 = Fluid, 2 = Struktur
5475 bool callFillComplete)
5476{
5477 DomainConstPtr_Type domain = domainVec_.at(FEloc);
5478
5479 MapConstPtr_Type mapInterfaceVecField = domain->getInterfaceMapVecFieldUnique(); // Interface-Map in der Interface-Nummerierung
5480 MapConstPtr_Type mapGlobalInterfaceVecField = domain->getGlobalInterfaceMapVecFieldUnique(); // Interface-Map in der globalen Nummerierung
5481
5482 MapConstPtr_Type mapFieldPartial = domain->getGlobalInterfaceMapVecFieldPartial();
5483
5484 Teuchos::Array<SC> value( 1, 0. );
5485 value[0] = 1.0; // da Einheitsmatrix
5486 Teuchos::Array<GO> indices( 1, 0 );
5487
5488 GO dofGlobal, dofLocal;
5489
5490 for(int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++)
5491 {
5492 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
5493 if ( mapFieldPartial->getLocalElement( dofGlobal ) == Teuchos::OrdinalTraits<LO>::invalid() ) {
5494 // Globale ID des Interface-Knotens bzgl. der Globalen oder Interface-Nummerierung
5495 dofGlobal = mapInterfaceVecField->getGlobalElement( k );
5496 indices[0] = dofGlobal;
5497 C->insertGlobalValues(dofGlobal, indices(), value());
5498 }
5499 }
5500
5501 if (callFillComplete)
5502 C->fillComplete(mapInterfaceVecField, mapInterfaceVecField);
5503
5504}
5505
5506template <class SC, class LO, class GO, class NO>
5507void FE<SC,LO,GO,NO>::assemblyFSICoupling(int dim,
5508 std::string FEType,
5509 MatrixPtr_Type &C,
5510 MatrixPtr_Type &C_T,
5511 int FEloc1, // 0 = Fluid, 2 = Struktur
5512 int FEloc2, // 0 = Fluid, 2 = Struktur
5513 MapConstPtr_Type map1, // DomainMap: InterfaceMapVecFieldUnique = Spalten von C_T
5514 MapConstPtr_Type map2, // RangeMap: this->getDomain(0)->getMapVecFieldUnique() = Zeilen von C_T
5515 bool callFillComplete)
5516{
5517 // int FEloc = this->checkFE(dim,FEType);
5518
5519 DomainConstPtr_Type domain1 = domainVec_.at(FEloc1);
5520
5521 MapConstPtr_Type mapInterfaceVecField = domain1->getInterfaceMapVecFieldUnique(); // Interface-Map in der Interface-Nummerierung
5522
5523 MapConstPtr_Type mapGlobalInterfaceVecField;
5524 MapConstPtr_Type mapFieldPartial;
5525 if (FEloc1!=FEloc2){
5526 mapFieldPartial = domain1->getOtherGlobalInterfaceMapVecFieldPartial();
5527 mapGlobalInterfaceVecField = domain1->getOtherGlobalInterfaceMapVecFieldUnique();
5528 }
5529 else{
5530 mapFieldPartial = domain1->getGlobalInterfaceMapVecFieldPartial();
5531 mapGlobalInterfaceVecField = domain1->getGlobalInterfaceMapVecFieldUnique();
5532 }
5533
5534 Teuchos::Array<SC> value( 1, 0. );
5535 value[0] = 1.0; // da Einheitsmatrix
5536 Teuchos::Array<GO> indices( 1, 0 );
5537
5538 GO dofGlobal, dofLocal;
5539 if (mapFieldPartial.is_null()) {
5540 for(int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++)
5541 {
5542 // Globale ID des Interface-Knotens bzgl. der Globalen oder Interface-Nummerierung
5543 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
5544 dofLocal = mapInterfaceVecField->getGlobalElement(k);
5545
5546 indices[0] = dofLocal;
5547 C_T->insertGlobalValues(dofGlobal, indices(), value());
5548 indices[0] = dofGlobal;
5549 C->insertGlobalValues(dofLocal, indices(), value());
5550
5551 }
5552 }
5553 else{
5554 for(int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++) {
5555 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
5556 if ( mapFieldPartial->getLocalElement( dofGlobal ) != Teuchos::OrdinalTraits<LO>::invalid() ) {
5557
5558 dofLocal = mapInterfaceVecField->getGlobalElement(k);
5559
5560 indices[0] = dofLocal;
5561 C_T->insertGlobalValues(dofGlobal, indices(), value());
5562 indices[0] = dofGlobal;
5563 C->insertGlobalValues(dofLocal, indices(), value());
5564 }
5565 }
5566 }
5567
5568 if (callFillComplete)
5569 {
5570 // Erstes Argument: Domain (=Spalten von C_T)
5571 // Zweites Arguement: Range (=Zeilen von C_T)
5572 C_T->fillComplete(map1, map2);
5573 C->fillComplete(map2, map1);
5574 }
5575}
5576
5577
5578template <class SC, class LO, class GO, class NO>
5579void FE<SC,LO,GO,NO>::assemblyGeometryCoupling(int dim,
5580 std::string FEType,
5581 MatrixPtr_Type &C,
5582 int FEloc, // 0 = Fluid, 2 = Struktur, 4 = 0 = Geometrie
5583 MapConstPtr_Type map1, // Fluid-Interface-Map
5584 MapConstPtr_Type map2, // DomainMap: this->getDomain(2)->getMapVecFieldUnique() = Spalten von C
5585 MapConstPtr_Type map3, // RangeMap: this->getDomain(4)->getMapVecFieldUnique() = Zeilen von C
5586 bool callFillComplete)
5587{
5588
5589 DomainConstPtr_Type domain = domainVec_.at(FEloc);
5590
5591 MapConstPtr_Type mapInt = domain->getGlobalInterfaceMapVecFieldUnique(); // Interface-Map in der globalen Nummerierung
5592 MapConstPtr_Type mapOtherInt = domain->getOtherGlobalInterfaceMapVecFieldUnique(); // Interface-Map in der globalen Nummerierung von other. For FELoc=0 or =4, otherInterface has solid dofs
5593 MapConstPtr_Type mapPartInt = domain->getGlobalInterfaceMapVecFieldPartial();
5594 MapConstPtr_Type mapOtherPartInt = domain->getOtherGlobalInterfaceMapVecFieldPartial();
5595 Teuchos::Array<SC> value( 1, 0. );
5596 value[0] = 1.0; // da Einheitsmatrix
5597 Teuchos::Array<GO> indices( 1, 0 );
5598
5599 GO dofRow;
5600 if (mapPartInt.is_null()) {
5601 for(int k = 0; k < mapInt->getNodeNumElements(); k++){
5602 dofRow = mapInt->getGlobalElement(k);
5603 indices[0] = mapOtherInt->getGlobalElement(k);
5604 C->insertGlobalValues(dofRow, indices(), value());
5605 }
5606 }
5607 else{
5608 for(int k = 0; k < mapPartInt->getNodeNumElements(); k++){
5609 dofRow = mapPartInt->getGlobalElement(k);
5610 indices[0] = mapOtherPartInt->getGlobalElement(k);
5611 C->insertGlobalValues(dofRow, indices(), value());
5612 }
5613 }
5614 if (callFillComplete)
5615 {
5616 // (Domain, Range)
5617 C->fillComplete(map2, map3);
5618 }
5619}
5620
5621
5622template <class SC, class LO, class GO, class NO>
5623void FE<SC,LO,GO,NO>::assemblyShapeDerivativeVelocity(int dim,
5624 std::string FEType1, // P2
5625 std::string FEType2, // P1
5626 MatrixPtr_Type &D,
5627 int FEloc, // 0 = Fluid (Velocity)
5628 MultiVectorPtr_Type u, // Geschwindigkeit
5629 MultiVectorPtr_Type w, // Beschleunigung Gitter
5630 MultiVectorPtr_Type p, // Druck
5631 double dt, // Zeitschrittweite
5632 double rho, // Dichte vom Fluid
5633 double nu, // Viskositaet vom Fluid
5634 bool callFillComplete)
5635{
5636 // int FEloc = this->checkFE(dim,FEType1);
5637
5638 DomainConstPtr_Type domain = domainVec_.at(FEloc);
5639 ElementsPtr_Type elements = domain->getElementsC();
5640 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
5641 MapConstPtr_Type map = domain->getMapRepeated();
5642
5643 vec3D_dbl_ptr_Type dPhiU;
5644 vec2D_dbl_ptr_Type phiU;
5645 vec2D_dbl_ptr_Type phiP;
5646 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
5647 vec2D_dbl_ptr_Type quadPts;
5648
5649 // Hoechste Quadraturordnung angeben (= Zusaetzlicher Term wg. non-conservativ); bei P2/P1 hier Ordnung 6
5650 UN extraDeg = 2*Helper::determineDegree( dim, FEType1, Helper::Deriv1);
5651 UN deg = 2*Helper::determineDegree( dim, FEType1, Helper::Deriv0) + extraDeg;
5652
5653 Helper::getDPhi(dPhiU, weights, dim, FEType1, deg);
5654 Helper::getPhi(phiU, weights, dim, FEType1, deg);
5655 Helper::getPhi(phiP, weights, dim, FEType2, deg);
5656 Helper::getQuadratureValues(dim, deg, quadPts, weights,FEType1);
5657
5658 // SC = double, GO = long, UN = int
5659 SC detB;
5660 SC absDetB;
5661 SmallMatrix<SC> B(dim);
5662 SmallMatrix<SC> Binv(dim);
5663 GO glob_i, glob_j;
5664
5665 // Der nichtlineare Teil als Array
5666 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
5667 Teuchos::ArrayRCP< const SC > wArray = w->getData(0);
5668 Teuchos::ArrayRCP< const SC > pArray = p->getData(0);
5669
5670 if (dim == 2)
5671 {
5672 double val11, val12, val21, val22;
5673 double valDK1_11, valDK1_12, valDK1_21, valDK1_22;
5674 double valDK2_11, valDK2_12, valDK2_21, valDK2_22;
5675 double valDN_11, valDN_12, valDN_21, valDN_22;
5676 double valDW_11, valDW_12, valDW_21, valDW_22;
5677 double valDP_11, valDP_12, valDP_21, valDP_22;
5678 double valDM_11, valDM_12, valDM_21, valDM_22;
5679 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
5680
5681 // Alle diskreten Vektoren aufstellen, dabei bezeichnet Xij = X_ij,
5682 // also i-te Komponenten von X nach der j-ten Variablen abgeleitet.
5683 // Der Gradient ist bei mir wie folgt definiert: \grad(u) = [u11, u12; u21 u22] = [grad(u_1)^T; grad(u_2)^T]
5684 vec2D_dbl_Type u1Loc(1, vec_dbl_Type(weights->size(), -1.));
5685 vec2D_dbl_Type u2Loc(1, vec_dbl_Type(weights->size(), -1.));
5686 vec2D_dbl_Type w1Loc(1, vec_dbl_Type(weights->size(), -1.));
5687 vec2D_dbl_Type w2Loc(1, vec_dbl_Type(weights->size(), -1.));
5688 vec2D_dbl_Type pLoc(1, vec_dbl_Type(weights->size(), -1.));
5689 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
5690 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
5691 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
5692 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
5693 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
5694 vec2D_dbl_Type w12(1, vec_dbl_Type(weights->size(), -1.));
5695 vec2D_dbl_Type w21(1, vec_dbl_Type(weights->size(), -1.));
5696 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
5697 vec2D_dbl_Type sigma11(1, vec_dbl_Type(weights->size(), -1.));
5698 vec2D_dbl_Type sigma12(1, vec_dbl_Type(weights->size(), -1.));
5699 vec2D_dbl_Type sigma21(1, vec_dbl_Type(weights->size(), -1.));
5700 vec2D_dbl_Type sigma22(1, vec_dbl_Type(weights->size(), -1.));
5701
5702 for (int T = 0; T < elements->numberElements(); T++)
5703 {
5704 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5705 p2 = pointsRep->at(elements->getElement(T).getNode(1));
5706 p3 = pointsRep->at(elements->getElement(T).getNode(2));
5707
5708 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
5709 detB = B.computeInverse(Binv);
5710 absDetB = std::fabs(detB);
5711
5712 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
5713 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
5714 applyBTinv( dPhiU, dPhiTransU, Binv ); //dPhiTrans berechnen
5715
5716 // Diskrete Vektoren u1, u2, w1 und w2 berechnen
5717 for(int k = 0; k < phiU->size(); k++) // Quadraturpunkte
5718 {
5719 u1Loc[0][k] = 0.0;
5720 u2Loc[0][k] = 0.0;
5721 w1Loc[0][k] = 0.0;
5722 w2Loc[0][k] = 0.0;
5723 for(int i = 0; i < phiU->at(0).size(); i++)
5724 {
5725 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
5726 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
5727 u1Loc[0][k] += uArray[index1] * phiU->at(k).at(i);
5728 u2Loc[0][k] += uArray[index2] * phiU->at(k).at(i);
5729 w1Loc[0][k] += wArray[index1] * phiU->at(k).at(i);
5730 w2Loc[0][k] += wArray[index2] * phiU->at(k).at(i);
5731
5732 }
5733 }
5734
5735 // Diskreten Vektor p berechnen
5736 // Beachte: phiP->size() = phiU->size()
5737 for(int k = 0; k < phiP->size(); k++) // Quadraturpunkte
5738 {
5739 pLoc[0][k] = 0.0;
5740 for(int i = 0; i < phiP->at(0).size(); i++)
5741 {
5742 // Die ersten Eintraege in der Elementliste sind P1
5743 // Alternativ elements2 holen
5744 LO index = elements->getElement(T).getNode(i) + 0;
5745 pLoc[0][k] += pArray[index] * phiP->at(k).at(i);
5746
5747 }
5748 }
5749
5750 // Diskrete Grad-Vektoren berechnen,
5751 // wobei z.B. w_ij = \frac{\partial w_i}{\partial x_j} ist.
5752 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
5753 {
5754 u11[0][k] = 0.0;
5755 u12[0][k] = 0.0;
5756 u21[0][k] = 0.0;
5757 u22[0][k] = 0.0;
5758 w11[0][k] = 0.0;
5759 w12[0][k] = 0.0;
5760 w21[0][k] = 0.0;
5761 w22[0][k] = 0.0;
5762 for(int i = 0; i < dPhiTransU[0].size(); i++)
5763 {
5764 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
5765 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
5766 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
5767 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
5768 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
5769 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
5770 w11[0][k] += wArray[index1] * dPhiTransU[k][i][0];
5771 w12[0][k] += wArray[index1] * dPhiTransU[k][i][1];
5772 w21[0][k] += wArray[index2] * dPhiTransU[k][i][0];
5773 w22[0][k] += wArray[index2] * dPhiTransU[k][i][1];
5774
5775 }
5776 }
5777
5778 // Diskretes \sigma = \rho * \nu * ( grad u + (grad u)^T ) - pI berechnen
5779 // Beachte: phiP->size() = phiU->size()
5780 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
5781 {
5782 sigma11[0][k] = rho * nu * (u11[0][k] + u11[0][k]) - pLoc[0][k];
5783 sigma12[0][k] = rho * nu * (u12[0][k] + u21[0][k]);
5784 sigma21[0][k] = rho * nu * (u21[0][k] + u12[0][k]);
5785 sigma22[0][k] = rho * nu * (u22[0][k] + u22[0][k]) - pLoc[0][k];
5786 }
5787
5788
5789 for (int i = 0; i < dPhiU->at(0).size(); i++)
5790 {
5791 Teuchos::Array<SC> value11( 1, 0. ); // x-x
5792 Teuchos::Array<SC> value12( 1, 0. ); // x-y
5793 Teuchos::Array<SC> value21( 1, 0. ); // y-x
5794 Teuchos::Array<SC> value22( 1, 0. ); // y-y
5795 Teuchos::Array<GO> indices( 1, 0 );
5796
5797 for (int j = 0; j < dPhiU->at(0).size(); j++)
5798 {
5799 // DK1
5800 valDK1_11 = 0.0;
5801 valDK1_12 = 0.0;
5802 valDK1_21 = 0.0;
5803 valDK1_22 = 0.0;
5804
5805 // DK2
5806 valDK2_11 = 0.0;
5807 valDK2_12 = 0.0;
5808 valDK2_21 = 0.0;
5809 valDK2_22 = 0.0;
5810
5811 // DN
5812 valDN_11 = 0.0;
5813 valDN_12 = 0.0;
5814 valDN_21 = 0.0;
5815 valDN_22 = 0.0;
5816
5817 // DW
5818 valDW_11 = 0.0;
5819 valDW_12 = 0.0;
5820 valDW_21 = 0.0;
5821 valDW_22 = 0.0;
5822
5823 // DP
5824 valDP_11 = 0.0;
5825 valDP_12 = 0.0;
5826 valDP_21 = 0.0;
5827 valDP_22 = 0.0;
5828
5829 // DM
5830 valDM_11 = 0.0;
5831 valDM_12 = 0.0;
5832 valDM_21 = 0.0;
5833 valDM_22 = 0.0;
5834
5835 for (int k = 0; k < dPhiU->size(); k++)
5836 {
5837 // DK1
5838 valDK1_11 = valDK1_11 + weights->at(k) *
5839 ( 2 * u11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
5840 u11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
5841 u21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5842 valDK1_12 = valDK1_12 + weights->at(k) *
5843 ( 2 * u12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
5844 u12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
5845 u22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5846 valDK1_21 = valDK1_21 + weights->at(k) *
5847 ( u11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5848 u21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
5849 2 * u21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] );
5850 valDK1_22 = valDK1_22 + weights->at(k) *
5851 ( u12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5852 u22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
5853 2 * u22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] );
5854
5855 // DK2
5856 valDK2_11 = valDK2_11 + weights->at(k) *
5857 ( -sigma12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5858 sigma12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5859 valDK2_12 = valDK2_12 + weights->at(k) *
5860 ( sigma11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5861 -sigma11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5862 valDK2_21 = valDK2_21 + weights->at(k) *
5863 ( -sigma22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5864 sigma22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5865 valDK2_22 = valDK2_22 + weights->at(k) *
5866 ( sigma21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
5867 -sigma21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
5868
5869 // DN
5870 valDN_11 = valDN_11 + weights->at(k) *
5871 ( -(u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][1] * u11[0][k] * phiU->at(k).at(i) +
5872 (u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][0] * u12[0][k] * phiU->at(k).at(i) );
5873 valDN_12 = valDN_12 + weights->at(k) *
5874 ( (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][1] * u11[0][k] * phiU->at(k).at(i) -
5875 (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][0] * u12[0][k] * phiU->at(k).at(i) );
5876 valDN_21 = valDN_21 + weights->at(k) *
5877 ( -(u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][1] * u21[0][k] * phiU->at(k).at(i) +
5878 (u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][0] * u22[0][k] * phiU->at(k).at(i) );
5879 valDN_22 = valDN_22 + weights->at(k) *
5880 ( (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][1] * u21[0][k] * phiU->at(k).at(i) -
5881 (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][0] * u22[0][k] * phiU->at(k).at(i) );
5882
5883 // DW
5884 valDW_11 = valDW_11 + weights->at(k) *
5885 ( u11[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
5886 valDW_12 = valDW_12 + weights->at(k) *
5887 ( u12[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
5888 valDW_21 = valDW_21 + weights->at(k) *
5889 ( u21[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
5890 valDW_22 = valDW_22 + weights->at(k) *
5891 ( u22[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
5892
5893 // DP
5894 valDP_11 = valDP_11 + weights->at(k) *
5895 ( ( -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] ) * u1Loc[0][k] * phiU->at(k).at(i) );
5896 valDP_12 = valDP_12 + weights->at(k) *
5897 ( ( w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] ) * u1Loc[0][k] * phiU->at(k).at(i) );
5898 valDP_21 = valDP_21 + weights->at(k) *
5899 ( ( -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] ) * u2Loc[0][k] * phiU->at(k).at(i) );
5900 valDP_22 = valDP_22 + weights->at(k) *
5901 ( ( w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] ) * u2Loc[0][k] * phiU->at(k).at(i) );
5902
5903 // DM
5904 valDM_11 = valDM_11 + weights->at(k) *
5905 ( dPhiTransU[k][j][0] * u1Loc[0][k] * phiU->at(k).at(i) );
5906 valDM_12 = valDM_12 + weights->at(k) *
5907 ( dPhiTransU[k][j][1] * u1Loc[0][k] * phiU->at(k).at(i) );
5908 valDM_21 = valDM_21 + weights->at(k) *
5909 ( dPhiTransU[k][j][0] * u2Loc[0][k] * phiU->at(k).at(i) );
5910 valDM_22 = valDM_22 + weights->at(k) *
5911 ( dPhiTransU[k][j][1] * u2Loc[0][k] * phiU->at(k).at(i) );
5912 }
5913
5914 val11 = -rho*nu*valDK1_11 + valDK2_11 + rho*valDN_11 - rho*valDP_11 - (1.0/dt)*rho*valDW_11 + (0.5/dt)*rho*valDM_11;
5915 val12 = -rho*nu*valDK1_12 + valDK2_12 + rho*valDN_12 - rho*valDP_12 - (1.0/dt)*rho*valDW_12 + (0.5/dt)*rho*valDM_12;
5916 val21 = -rho*nu*valDK1_21 + valDK2_21 + rho*valDN_21 - rho*valDP_21 - (1.0/dt)*rho*valDW_21 + (0.5/dt)*rho*valDM_21;
5917 val22 = -rho*nu*valDK1_22 + valDK2_22 + rho*valDN_22 - rho*valDP_22 - (1.0/dt)*rho*valDW_22 + (0.5/dt)*rho*valDM_22;
5918
5919 val11 = absDetB * val11;
5920 val12 = absDetB * val12;
5921 val21 = absDetB * val21;
5922 val22 = absDetB * val22;
5923
5924 value11[0] = val11; // x-x
5925 value12[0] = val12; // x-y
5926 value21[0] = val21; // y-x
5927 value22[0] = val22; // y-y
5928
5929 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
5930 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
5931 indices[0] = glob_j;
5932
5933 D->insertGlobalValues(glob_i, indices(), value11()); // x-x
5934 D->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
5935 glob_j++;
5936 indices[0] = glob_j;
5937 D->insertGlobalValues(glob_i, indices(), value12()); // x-y
5938 D->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
5939 }
5940 }
5941 }
5942 if (callFillComplete)
5943 {
5944 D->fillComplete();
5945 }
5946 }
5947 else if(dim == 3)
5948 {
5949 double val11, val12, val13, val21, val22, val23, val31, val32, val33;
5950 double valDK1_11, valDK1_12, valDK1_13, valDK1_21, valDK1_22, valDK1_23, valDK1_31, valDK1_32, valDK1_33;
5951 double valDK2_11, valDK2_12, valDK2_13, valDK2_21, valDK2_22, valDK2_23, valDK2_31, valDK2_32, valDK2_33;
5952 double valDN_11, valDN_12, valDN_13, valDN_21, valDN_22, valDN_23, valDN_31, valDN_32, valDN_33;
5953 double valDW_11, valDW_12, valDW_13, valDW_21, valDW_22, valDW_23, valDW_31, valDW_32, valDW_33;
5954 double valDP_11, valDP_12, valDP_13, valDP_21, valDP_22, valDP_23, valDP_31, valDP_32, valDP_33;
5955 double valDM_11, valDM_12, valDM_13, valDM_21, valDM_22, valDM_23, valDM_31, valDM_32, valDM_33;
5956 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
5957
5958 // Alle diskreten Vektoren aufstellen, dabei bezeichnet Xij = X_ij,
5959 // also i-te Komponenten von X nach der j-ten Variablen abgeleitet.
5960 // Der Gradient ist bei mir wie folgt definiert: \grad(u) = [u11, u12; u21 u22] = [grad(u_1)^T; grad(u_2)^T]
5961 vec2D_dbl_Type u1Loc(1, vec_dbl_Type(weights->size(), -1.));
5962 vec2D_dbl_Type u2Loc(1, vec_dbl_Type(weights->size(), -1.));
5963 vec2D_dbl_Type u3Loc(1, vec_dbl_Type(weights->size(), -1.));
5964 vec2D_dbl_Type w1Loc(1, vec_dbl_Type(weights->size(), -1.));
5965 vec2D_dbl_Type w2Loc(1, vec_dbl_Type(weights->size(), -1.));
5966 vec2D_dbl_Type w3Loc(1, vec_dbl_Type(weights->size(), -1.));
5967 vec2D_dbl_Type pLoc(1, vec_dbl_Type(weights->size(), -1.));
5968 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
5969 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
5970 vec2D_dbl_Type u13(1, vec_dbl_Type(weights->size(), -1.));
5971 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
5972 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
5973 vec2D_dbl_Type u23(1, vec_dbl_Type(weights->size(), -1.));
5974 vec2D_dbl_Type u31(1, vec_dbl_Type(weights->size(), -1.));
5975 vec2D_dbl_Type u32(1, vec_dbl_Type(weights->size(), -1.));
5976 vec2D_dbl_Type u33(1, vec_dbl_Type(weights->size(), -1.));
5977 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
5978 vec2D_dbl_Type w12(1, vec_dbl_Type(weights->size(), -1.));
5979 vec2D_dbl_Type w13(1, vec_dbl_Type(weights->size(), -1.));
5980 vec2D_dbl_Type w21(1, vec_dbl_Type(weights->size(), -1.));
5981 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
5982 vec2D_dbl_Type w23(1, vec_dbl_Type(weights->size(), -1.));
5983 vec2D_dbl_Type w31(1, vec_dbl_Type(weights->size(), -1.));
5984 vec2D_dbl_Type w32(1, vec_dbl_Type(weights->size(), -1.));
5985 vec2D_dbl_Type w33(1, vec_dbl_Type(weights->size(), -1.));
5986 vec2D_dbl_Type sigma11(1, vec_dbl_Type(weights->size(), -1.));
5987 vec2D_dbl_Type sigma12(1, vec_dbl_Type(weights->size(), -1.));
5988 vec2D_dbl_Type sigma13(1, vec_dbl_Type(weights->size(), -1.));
5989 vec2D_dbl_Type sigma21(1, vec_dbl_Type(weights->size(), -1.));
5990 vec2D_dbl_Type sigma22(1, vec_dbl_Type(weights->size(), -1.));
5991 vec2D_dbl_Type sigma23(1, vec_dbl_Type(weights->size(), -1.));
5992 vec2D_dbl_Type sigma31(1, vec_dbl_Type(weights->size(), -1.));
5993 vec2D_dbl_Type sigma32(1, vec_dbl_Type(weights->size(), -1.));
5994 vec2D_dbl_Type sigma33(1, vec_dbl_Type(weights->size(), -1.));
5995
5996 for (int T = 0; T < elements->numberElements(); T++)
5997 {
5998 p1 = pointsRep->at(elements->getElement(T).getNode(0));
5999 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6000 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6001 p4 = pointsRep->at(elements->getElement(T).getNode(3));
6002
6003 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
6004 detB = B.computeInverse(Binv);
6005 absDetB = std::fabs(detB);
6006
6007 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
6008 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
6009 applyBTinv( dPhiU, dPhiTransU, Binv ); //dPhiTrans berechnen
6010
6011 // Diskrete Vektoren u1, u2, w1 und w2 berechnen
6012 for(int k = 0; k < phiU->size(); k++) // Quadraturpunkte
6013 {
6014 u1Loc[0][k] = 0.0;
6015 u2Loc[0][k] = 0.0;
6016 u3Loc[0][k] = 0.0;
6017 w1Loc[0][k] = 0.0;
6018 w2Loc[0][k] = 0.0;
6019 w3Loc[0][k] = 0.0;
6020 for(int i = 0; i < phiU->at(0).size(); i++)
6021 {
6022 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
6023 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
6024 LO index3 = dim * elements->getElement(T).getNode(i) + 2; // z
6025 u1Loc[0][k] += uArray[index1] * phiU->at(k).at(i);
6026 u2Loc[0][k] += uArray[index2] * phiU->at(k).at(i);
6027 u3Loc[0][k] += uArray[index3] * phiU->at(k).at(i);
6028 w1Loc[0][k] += wArray[index1] * phiU->at(k).at(i);
6029 w2Loc[0][k] += wArray[index2] * phiU->at(k).at(i);
6030 w3Loc[0][k] += wArray[index3] * phiU->at(k).at(i);
6031 }
6032 }
6033
6034 // Diskreten Vektor p berechnen
6035 // Beachte: phiP->size() = phiU->size()
6036 for(int k = 0; k < phiP->size(); k++) // Quadraturpunkte
6037 {
6038 pLoc[0][k] = 0.0;
6039 for(int i = 0; i < phiP->at(0).size(); i++)
6040 {
6041 // Die ersten Eintraege in der Elementliste sind P1
6042 LO index = elements->getElement(T).getNode(i) + 0;
6043 pLoc[0][k] += pArray[index] * phiP->at(k).at(i);
6044 }
6045 }
6046
6047 // Diskrete Grad-Vektoren berechnen,
6048 // wobei z.B. w_ij = \frac{\partial w_i}{\partial x_j} ist.
6049 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
6050 {
6051 u11[0][k] = 0.0;
6052 u12[0][k] = 0.0;
6053 u13[0][k] = 0.0;
6054 u21[0][k] = 0.0;
6055 u22[0][k] = 0.0;
6056 u23[0][k] = 0.0;
6057 u31[0][k] = 0.0;
6058 u32[0][k] = 0.0;
6059 u33[0][k] = 0.0;
6060 w11[0][k] = 0.0;
6061 w12[0][k] = 0.0;
6062 w13[0][k] = 0.0;
6063 w21[0][k] = 0.0;
6064 w22[0][k] = 0.0;
6065 w23[0][k] = 0.0;
6066 w31[0][k] = 0.0;
6067 w32[0][k] = 0.0;
6068 w33[0][k] = 0.0;
6069 for(int i = 0; i < dPhiTransU[0].size(); i++)
6070 {
6071 LO index1 = dim * elements->getElement(T).getNode(i) + 0; // x
6072 LO index2 = dim * elements->getElement(T).getNode(i) + 1; // y
6073 LO index3 = dim * elements->getElement(T).getNode(i) + 2; // z
6074 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
6075 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
6076 u13[0][k] += uArray[index1] * dPhiTransU[k][i][2];
6077 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
6078 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
6079 u23[0][k] += uArray[index2] * dPhiTransU[k][i][2];
6080 u31[0][k] += uArray[index3] * dPhiTransU[k][i][0];
6081 u32[0][k] += uArray[index3] * dPhiTransU[k][i][1];
6082 u33[0][k] += uArray[index3] * dPhiTransU[k][i][2];
6083 w11[0][k] += wArray[index1] * dPhiTransU[k][i][0];
6084 w12[0][k] += wArray[index1] * dPhiTransU[k][i][1];
6085 w13[0][k] += wArray[index1] * dPhiTransU[k][i][2];
6086 w21[0][k] += wArray[index2] * dPhiTransU[k][i][0];
6087 w22[0][k] += wArray[index2] * dPhiTransU[k][i][1];
6088 w23[0][k] += wArray[index2] * dPhiTransU[k][i][2];
6089 w31[0][k] += wArray[index3] * dPhiTransU[k][i][0];
6090 w32[0][k] += wArray[index3] * dPhiTransU[k][i][1];
6091 w33[0][k] += wArray[index3] * dPhiTransU[k][i][2];
6092 }
6093 }
6094
6095 // Diskretes \sigma = \rho * \nu * ( grad u + (grad u)^T ) - pI berechnen
6096 // Beachte: phiP->size() = phiU->size()
6097 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
6098 {
6099 sigma11[0][k] = rho * nu * (u11[0][k] + u11[0][k]) - pLoc[0][k];
6100 sigma12[0][k] = rho * nu * (u12[0][k] + u21[0][k]);
6101 sigma13[0][k] = rho * nu * (u13[0][k] + u31[0][k]);
6102 sigma21[0][k] = rho * nu * (u21[0][k] + u12[0][k]);
6103 sigma22[0][k] = rho * nu * (u22[0][k] + u22[0][k]) - pLoc[0][k];
6104 sigma23[0][k] = rho * nu * (u23[0][k] + u32[0][k]);
6105 sigma31[0][k] = rho * nu * (u31[0][k] + u13[0][k]);
6106 sigma32[0][k] = rho * nu * (u32[0][k] + u23[0][k]);
6107 sigma33[0][k] = rho * nu * (u33[0][k] + u33[0][k]) - pLoc[0][k];
6108 }
6109
6110
6111 for (int i = 0; i < dPhiU->at(0).size(); i++)
6112 {
6113 Teuchos::Array<SC> value11( 1, 0. ); // x-x
6114 Teuchos::Array<SC> value12( 1, 0. ); // x-y
6115 Teuchos::Array<SC> value13( 1, 0. ); // x-z
6116 Teuchos::Array<SC> value21( 1, 0. ); // y-x
6117 Teuchos::Array<SC> value22( 1, 0. ); // y-y
6118 Teuchos::Array<SC> value23( 1, 0. ); // y-z
6119 Teuchos::Array<SC> value31( 1, 0. ); // z-x
6120 Teuchos::Array<SC> value32( 1, 0. ); // z-y
6121 Teuchos::Array<SC> value33( 1, 0. ); // z-z
6122 Teuchos::Array<GO> indices( 1, 0 );
6123
6124 for (int j = 0; j < dPhiU->at(0).size(); j++)
6125 {
6126 // DK1
6127 valDK1_11 = 0.0;
6128 valDK1_12 = 0.0;
6129 valDK1_13 = 0.0;
6130 valDK1_21 = 0.0;
6131 valDK1_22 = 0.0;
6132 valDK1_23 = 0.0;
6133 valDK1_31 = 0.0;
6134 valDK1_32 = 0.0;
6135 valDK1_33 = 0.0;
6136
6137 // DK2
6138 valDK2_11 = 0.0;
6139 valDK2_12 = 0.0;
6140 valDK2_13 = 0.0;
6141 valDK2_21 = 0.0;
6142 valDK2_22 = 0.0;
6143 valDK2_23 = 0.0;
6144 valDK2_31 = 0.0;
6145 valDK2_32 = 0.0;
6146 valDK2_33 = 0.0;
6147
6148 // DN
6149 valDN_11 = 0.0;
6150 valDN_12 = 0.0;
6151 valDN_13 = 0.0;
6152 valDN_21 = 0.0;
6153 valDN_22 = 0.0;
6154 valDN_23 = 0.0;
6155 valDN_31 = 0.0;
6156 valDN_32 = 0.0;
6157 valDN_33 = 0.0;
6158
6159 // DW
6160 valDW_11 = 0.0;
6161 valDW_12 = 0.0;
6162 valDW_13 = 0.0;
6163 valDW_21 = 0.0;
6164 valDW_22 = 0.0;
6165 valDW_23 = 0.0;
6166 valDW_31 = 0.0;
6167 valDW_32 = 0.0;
6168 valDW_33 = 0.0;
6169
6170 // DP
6171 valDP_11 = 0.0;
6172 valDP_12 = 0.0;
6173 valDP_13 = 0.0;
6174 valDP_21 = 0.0;
6175 valDP_22 = 0.0;
6176 valDP_23 = 0.0;
6177 valDP_31 = 0.0;
6178 valDP_32 = 0.0;
6179 valDP_33 = 0.0;
6180
6181 // DM
6182 valDM_11 = 0.0;
6183 valDM_12 = 0.0;
6184 valDM_13 = 0.0;
6185 valDM_21 = 0.0;
6186 valDM_22 = 0.0;
6187 valDM_23 = 0.0;
6188 valDM_31 = 0.0;
6189 valDM_32 = 0.0;
6190 valDM_33 = 0.0;
6191
6192 for (int k = 0; k < dPhiU->size(); k++)
6193 {
6194 // DK1
6195 valDK1_11 = valDK1_11 + weights->at(k) *
6196 ( 2 * u11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
6197 ( u11[0][k] * dPhiTransU[k][j][1] + u21[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
6198 ( u11[0][k] * dPhiTransU[k][j][2] + u31[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
6199 valDK1_12 = valDK1_12 + weights->at(k) *
6200 ( 2 * u12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
6201 ( u12[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
6202 ( u12[0][k] * dPhiTransU[k][j][2] + u32[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
6203 valDK1_13 = valDK1_13 + weights->at(k) *
6204 ( 2 * u13[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
6205 ( u13[0][k] * dPhiTransU[k][j][1] + u23[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
6206 ( u13[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
6207 valDK1_21 = valDK1_21 + weights->at(k) *
6208 ( ( u21[0][k] * dPhiTransU[k][j][0] + u11[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
6209 2 * u21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
6210 ( u21[0][k] * dPhiTransU[k][j][2] + u31[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6211 valDK1_22 = valDK1_22 + weights->at(k) *
6212 ( ( u22[0][k] * dPhiTransU[k][j][0] + u12[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
6213 2 * u22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
6214 ( u22[0][k] * dPhiTransU[k][j][2] + u32[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6215 valDK1_23 = valDK1_23 + weights->at(k) *
6216 ( ( u23[0][k] * dPhiTransU[k][j][0] + u13[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
6217 2 * u23[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
6218 ( u23[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6219 valDK1_31 = valDK1_31 + weights->at(k) *
6220 ( ( u31[0][k] * dPhiTransU[k][j][0] + u11[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6221 ( u31[0][k] * dPhiTransU[k][j][1] + u21[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
6222 2 * u31[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
6223 valDK1_32 = valDK1_32 + weights->at(k) *
6224 ( ( u32[0][k] * dPhiTransU[k][j][0] + u12[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6225 ( u32[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
6226 2 * u32[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
6227 valDK1_33 = valDK1_33 + weights->at(k) *
6228 ( ( u33[0][k] * dPhiTransU[k][j][0] + u13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6229 ( u33[0][k] * dPhiTransU[k][j][1] + u23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
6230 2 * u33[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
6231
6232 // DK2
6233 valDK2_11 = valDK2_11 + weights->at(k) *
6234 ( ( -sigma12[0][k] * dPhiTransU[k][j][1] - sigma13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6235 sigma12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
6236 sigma13[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
6237 valDK2_12 = valDK2_12 + weights->at(k) *
6238 ( sigma11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
6239 ( -sigma11[0][k] * dPhiTransU[k][j][0] - sigma13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
6240 sigma13[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
6241 valDK2_13 = valDK2_13 + weights->at(k) *
6242 ( sigma11[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
6243 sigma12[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
6244 ( -sigma11[0][k] * dPhiTransU[k][j][0] - sigma12[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6245 valDK2_21 = valDK2_21 + weights->at(k) *
6246 ( ( -sigma22[0][k] * dPhiTransU[k][j][1] - sigma23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6247 sigma22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
6248 sigma23[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
6249 valDK2_22 = valDK2_22 + weights->at(k) *
6250 ( sigma21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
6251 ( -sigma21[0][k] * dPhiTransU[k][j][0] - sigma23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
6252 sigma23[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
6253 valDK2_23 = valDK2_23 + weights->at(k) *
6254 ( sigma21[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
6255 sigma22[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
6256 ( -sigma21[0][k] * dPhiTransU[k][j][0] - sigma22[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6257 valDK2_31 = valDK2_31 + weights->at(k) *
6258 ( ( -sigma32[0][k] * dPhiTransU[k][j][1] - sigma33[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
6259 sigma32[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
6260 sigma33[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
6261 valDK2_32 = valDK2_32 + weights->at(k) *
6262 ( sigma31[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
6263 ( -sigma31[0][k] * dPhiTransU[k][j][0] - sigma33[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
6264 sigma33[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
6265 valDK2_33 = valDK2_33 + weights->at(k) *
6266 ( sigma31[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
6267 sigma32[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
6268 ( -sigma31[0][k] * dPhiTransU[k][j][0] - sigma32[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
6269
6270 // DN
6271 double ZN_11; // Die Z_i fuer das DN wie in der Masterarbeit definiert
6272 double ZN_12;
6273 double ZN_13;
6274 double ZN_21;
6275 double ZN_22;
6276 double ZN_23;
6277 double ZN_31;
6278 double ZN_32;
6279 double ZN_33;
6280 ZN_11 = - ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][1] - ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][2];
6281 ZN_12 = ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][0];
6282 ZN_13 = ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][0];
6283 ZN_21 = ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][1];
6284 ZN_22 = - ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][0] - ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][2];
6285 ZN_23 = ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][1];
6286 ZN_31 = ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][2];
6287 ZN_32 = ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][2];
6288 ZN_33 = - ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][0] - ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][1];
6289
6290 valDN_11 = valDN_11 + weights->at(k) *
6291 ( ZN_11 * u11[0][k] * phiU->at(k).at(i) +
6292 ZN_12 * u12[0][k] * phiU->at(k).at(i) +
6293 ZN_13 * u13[0][k] * phiU->at(k).at(i) );
6294 valDN_12 = valDN_12 + weights->at(k) *
6295 ( ZN_21 * u11[0][k] * phiU->at(k).at(i) +
6296 ZN_22 * u12[0][k] * phiU->at(k).at(i) +
6297 ZN_23 * u13[0][k] * phiU->at(k).at(i) );
6298 valDN_13 = valDN_13 + weights->at(k) *
6299 ( ZN_31 * u11[0][k] * phiU->at(k).at(i) +
6300 ZN_32 * u12[0][k] * phiU->at(k).at(i) +
6301 ZN_33 * u13[0][k] * phiU->at(k).at(i) );
6302 valDN_21 = valDN_21 + weights->at(k) *
6303 ( ZN_11 * u21[0][k] * phiU->at(k).at(i) +
6304 ZN_12 * u22[0][k] * phiU->at(k).at(i) +
6305 ZN_13 * u23[0][k] * phiU->at(k).at(i) );
6306 valDN_22 = valDN_22 + weights->at(k) *
6307 ( ZN_21 * u21[0][k] * phiU->at(k).at(i) +
6308 ZN_22 * u22[0][k] * phiU->at(k).at(i) +
6309 ZN_23 * u23[0][k] * phiU->at(k).at(i) );
6310 valDN_23 = valDN_23 + weights->at(k) *
6311 ( ZN_31 * u21[0][k] * phiU->at(k).at(i) +
6312 ZN_32 * u22[0][k] * phiU->at(k).at(i) +
6313 ZN_33 * u23[0][k] * phiU->at(k).at(i) );
6314 valDN_31 = valDN_31 + weights->at(k) *
6315 ( ZN_11 * u31[0][k] * phiU->at(k).at(i) +
6316 ZN_12 * u32[0][k] * phiU->at(k).at(i) +
6317 ZN_13 * u33[0][k] * phiU->at(k).at(i) );
6318 valDN_32 = valDN_32 + weights->at(k) *
6319 ( ZN_21 * u31[0][k] * phiU->at(k).at(i) +
6320 ZN_22 * u32[0][k] * phiU->at(k).at(i) +
6321 ZN_23 * u33[0][k] * phiU->at(k).at(i) );
6322 valDN_33 = valDN_33 + weights->at(k) *
6323 ( ZN_31 * u31[0][k] * phiU->at(k).at(i) +
6324 ZN_32 * u32[0][k] * phiU->at(k).at(i) +
6325 ZN_33 * u33[0][k] * phiU->at(k).at(i) );
6326
6327 // DW
6328 valDW_11 = valDW_11 + weights->at(k) *
6329 ( u11[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6330 valDW_12 = valDW_12 + weights->at(k) *
6331 ( u12[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6332 valDW_13 = valDW_13 + weights->at(k) *
6333 ( u13[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6334 valDW_21 = valDW_21 + weights->at(k) *
6335 ( u21[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6336 valDW_22 = valDW_22 + weights->at(k) *
6337 ( u22[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6338 valDW_23 = valDW_23 + weights->at(k) *
6339 ( u23[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6340 valDW_31 = valDW_31 + weights->at(k) *
6341 ( u31[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6342 valDW_32 = valDW_32 + weights->at(k) *
6343 ( u32[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6344 valDW_33 = valDW_33 + weights->at(k) *
6345 ( u33[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
6346
6347 // DP
6348 double ZP_1; // Die Z_i fuer das DP wie in der Masterarbeit definiert
6349 double ZP_2;
6350 double ZP_3;
6351 ZP_1 = -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] -
6352 w31[0][k] * dPhiTransU[k][j][2] + w33[0][k] * dPhiTransU[k][j][0];
6353 ZP_2 = w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] -
6354 w32[0][k] * dPhiTransU[k][j][2] + w33[0][k] * dPhiTransU[k][j][1];
6355 ZP_3 = w11[0][k] * dPhiTransU[k][j][2] - w13[0][k] * dPhiTransU[k][j][0] +
6356 w22[0][k] * dPhiTransU[k][j][2] - w23[0][k] * dPhiTransU[k][j][1];
6357
6358 valDP_11 = valDP_11 + weights->at(k) *
6359 ( ZP_1 * u1Loc[0][k] * phiU->at(k).at(i) );
6360 valDP_12 = valDP_12 + weights->at(k) *
6361 ( ZP_2 * u1Loc[0][k] * phiU->at(k).at(i) );
6362 valDP_13 = valDP_13 + weights->at(k) *
6363 ( ZP_3 * u1Loc[0][k] * phiU->at(k).at(i) );
6364 valDP_21 = valDP_21 + weights->at(k) *
6365 ( ZP_1 * u2Loc[0][k] * phiU->at(k).at(i) );
6366 valDP_22 = valDP_22 + weights->at(k) *
6367 ( ZP_2 * u2Loc[0][k] * phiU->at(k).at(i) );
6368 valDP_23 = valDP_23 + weights->at(k) *
6369 ( ZP_3 * u2Loc[0][k] * phiU->at(k).at(i) );
6370 valDP_31 = valDP_31 + weights->at(k) *
6371 ( ZP_1 * u3Loc[0][k] * phiU->at(k).at(i) );
6372 valDP_32 = valDP_32 + weights->at(k) *
6373 ( ZP_2 * u3Loc[0][k] * phiU->at(k).at(i) );
6374 valDP_33 = valDP_33 + weights->at(k) *
6375 ( ZP_3 * u3Loc[0][k] * phiU->at(k).at(i) );
6376
6377 // DM
6378 valDM_11 = valDM_11 + weights->at(k) *
6379 ( dPhiTransU[k][j][0] * u1Loc[0][k] * phiU->at(k).at(i) );
6380 valDM_12 = valDM_12 + weights->at(k) *
6381 ( dPhiTransU[k][j][1] * u1Loc[0][k] * phiU->at(k).at(i) );
6382 valDM_13 = valDM_13 + weights->at(k) *
6383 ( dPhiTransU[k][j][2] * u1Loc[0][k] * phiU->at(k).at(i) );
6384 valDM_21 = valDM_21 + weights->at(k) *
6385 ( dPhiTransU[k][j][0] * u2Loc[0][k] * phiU->at(k).at(i) );
6386 valDM_22 = valDM_22 + weights->at(k) *
6387 ( dPhiTransU[k][j][1] * u2Loc[0][k] * phiU->at(k).at(i) );
6388 valDM_23 = valDM_23 + weights->at(k) *
6389 ( dPhiTransU[k][j][2] * u2Loc[0][k] * phiU->at(k).at(i) );
6390 valDM_31 = valDM_31 + weights->at(k) *
6391 ( dPhiTransU[k][j][0] * u3Loc[0][k] * phiU->at(k).at(i) );
6392 valDM_32 = valDM_32 + weights->at(k) *
6393 ( dPhiTransU[k][j][1] * u3Loc[0][k] * phiU->at(k).at(i) );
6394 valDM_33 = valDM_33 + weights->at(k) *
6395 ( dPhiTransU[k][j][2] * u3Loc[0][k] * phiU->at(k).at(i) );
6396 }
6397
6398 val11 = -rho*nu*valDK1_11 + valDK2_11 + rho*valDN_11 - rho*valDP_11 - (1.0/dt)*rho*valDW_11 + (0.5/dt)*rho*valDM_11;
6399 val12 = -rho*nu*valDK1_12 + valDK2_12 + rho*valDN_12 - rho*valDP_12 - (1.0/dt)*rho*valDW_12 + (0.5/dt)*rho*valDM_12;
6400 val13 = -rho*nu*valDK1_13 + valDK2_13 + rho*valDN_13 - rho*valDP_13 - (1.0/dt)*rho*valDW_13 + (0.5/dt)*rho*valDM_13;
6401 val21 = -rho*nu*valDK1_21 + valDK2_21 + rho*valDN_21 - rho*valDP_21 - (1.0/dt)*rho*valDW_21 + (0.5/dt)*rho*valDM_21;
6402 val22 = -rho*nu*valDK1_22 + valDK2_22 + rho*valDN_22 - rho*valDP_22 - (1.0/dt)*rho*valDW_22 + (0.5/dt)*rho*valDM_22;
6403 val23 = -rho*nu*valDK1_23 + valDK2_23 + rho*valDN_23 - rho*valDP_23 - (1.0/dt)*rho*valDW_23 + (0.5/dt)*rho*valDM_23;
6404 val31 = -rho*nu*valDK1_31 + valDK2_31 + rho*valDN_31 - rho*valDP_31 - (1.0/dt)*rho*valDW_31 + (0.5/dt)*rho*valDM_31;
6405 val32 = -rho*nu*valDK1_32 + valDK2_32 + rho*valDN_32 - rho*valDP_32 - (1.0/dt)*rho*valDW_32 + (0.5/dt)*rho*valDM_32;
6406 val33 = -rho*nu*valDK1_33 + valDK2_33 + rho*valDN_33 - rho*valDP_33 - (1.0/dt)*rho*valDW_33 + (0.5/dt)*rho*valDM_33;
6407
6408 val11 = absDetB * val11;
6409 val12 = absDetB * val12;
6410 val13 = absDetB * val13;
6411 val21 = absDetB * val21;
6412 val22 = absDetB * val22;
6413 val23 = absDetB * val23;
6414 val31 = absDetB * val31;
6415 val32 = absDetB * val32;
6416 val33 = absDetB * val33;
6417
6418 value11[0] = val11; // x-x
6419 value12[0] = val12; // x-y
6420 value13[0] = val13; // x-z
6421 value21[0] = val21; // y-x
6422 value22[0] = val22; // y-y
6423 value23[0] = val23; // y-z
6424 value31[0] = val31; // z-x
6425 value32[0] = val32; // z-y
6426 value33[0] = val33; // z-z
6427
6428
6429 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6430 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6431 indices[0] = glob_j;
6432
6433 D->insertGlobalValues(glob_i, indices(), value11()); // x-x
6434 D->insertGlobalValues(glob_i+1, indices(), value21()); // y-x
6435 D->insertGlobalValues(glob_i+2, indices(), value31()); // z-x
6436 glob_j++;
6437 indices[0] = glob_j;
6438 D->insertGlobalValues(glob_i, indices(), value12()); // x-y
6439 D->insertGlobalValues(glob_i+1, indices(), value22()); // y-y
6440 D->insertGlobalValues(glob_i+2, indices(), value32()); // z-y
6441 glob_j++;
6442 indices[0] = glob_j;
6443 D->insertGlobalValues(glob_i, indices(), value13()); // x-z
6444 D->insertGlobalValues(glob_i+1, indices(), value23()); // y-z
6445 D->insertGlobalValues(glob_i+2, indices(), value33()); // z-z
6446 }
6447 }
6448 }
6449 if (callFillComplete)
6450 {
6451 D->fillComplete();
6452 }
6453 }
6454
6455}
6456
6457
6458template <class SC, class LO, class GO, class NO>
6459void FE<SC,LO,GO,NO>::assemblyShapeDerivativeDivergence(int dim,
6460 std::string FEType1,
6461 std::string FEType2,
6462 MatrixPtr_Type &DB,
6463 int FEloc1, // 1 = Fluid-Pressure
6464 int FEloc2, // 0 = Fluid-Velocity
6465 MapConstPtr_Type map1_unique, // Pressure-Map
6466 MapConstPtr_Type map2_unique, // Velocity-Map unique als VecField
6467 MultiVectorPtr_Type u, // Geschwindigkeit
6468 bool callFillComplete)
6469{
6470 DomainConstPtr_Type domain1 = domainVec_.at(FEloc1);
6471 ElementsPtr_Type elements = domain1->getElementsC();
6472 vec2D_dbl_ptr_Type pointsRep = domain1->getPointsRepeated();
6473 MapConstPtr_Type map1_rep = domain1->getMapRepeated();
6474
6475 // Fuer die Fluid-Velocity-Map
6476 DomainConstPtr_Type domain2 = domainVec_.at(FEloc2);
6477 MapConstPtr_Type map2_rep = domain2->getMapRepeated();
6478 ElementsPtr_Type elements2 = domain2->getElementsC();
6479
6480 vec3D_dbl_ptr_Type dPhiU;
6481 vec2D_dbl_ptr_Type phiU;
6482 vec2D_dbl_ptr_Type phiP;
6483 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
6484 vec2D_dbl_ptr_Type quadPts;
6485
6486 UN extraDeg = Helper::determineDegree( dim, FEType1, Helper::Deriv1);
6487 UN deg = Helper::determineDegree( dim, FEType1, Helper::Deriv0) + 2*extraDeg;
6488
6489
6490 Helper::getDPhi(dPhiU, weights, dim, FEType1, deg);
6491 Helper::getPhi(phiU, weights, dim, FEType1, deg);
6492 Helper::getPhi(phiP, weights, dim, FEType2, deg);
6493 Helper::getQuadratureValues(dim, deg, quadPts, weights, FEType1);
6494
6495 // SC = double, GO = long, UN = int
6496 SC detB;
6497 SC absDetB;
6498 SmallMatrix<SC> B(dim);
6499 SmallMatrix<SC> Binv(dim);
6500 GO glob_i, glob_j;
6501
6502 // Der nichtlineare Teil als Array
6503 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
6504
6505 if (dim == 2)
6506 {
6507 double val1, val2;
6508 double valDB_1, valDB_2;
6509 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
6510
6511 // Alle diskreten Vektoren aufstellen, dabei bezeichnet Xij = X_ij,
6512 // also i-te Komponenten von X nach der j-ten Variablen abgeleitet.
6513 // Der Gradient ist bei mir wie folgt definiert: \grad(u) = [u11, u12; u21 u22] = [grad(u_1)^T; grad(u_2)^T]
6514 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
6515 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
6516 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
6517 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
6518
6519 for (int T = 0; T < elements->numberElements(); T++)
6520 {
6521 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6522 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6523 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6524
6525 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
6526 detB = B.computeInverse(Binv);
6527 absDetB = std::fabs(detB);
6528
6529 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
6530 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
6531 applyBTinv( dPhiU, dPhiTransU, Binv ); //dPhiTrans berechnen
6532
6533 // Diskrete Grad-Vektoren berechnen,
6534 // wobei z.B. w_ij = \frac{\partial w_i}{\partial x_j} ist.
6535 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
6536 {
6537 u11[0][k] = 0.0;
6538 u12[0][k] = 0.0;
6539 u21[0][k] = 0.0;
6540 u22[0][k] = 0.0;
6541 for(int i = 0; i < dPhiTransU[0].size(); i++)
6542 {
6543 LO index1 = dim * elements2->getElement(T).getNode(i) + 0; // x
6544 LO index2 = dim * elements2->getElement(T).getNode(i) + 1; // y
6545 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
6546 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
6547 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
6548 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
6549
6550 }
6551 }
6552
6553 for (int i = 0; i < phiP->at(0).size(); i++)
6554 {
6555 Teuchos::Array<SC> value1( 1, 0. ); // p-x
6556 Teuchos::Array<SC> value2( 1, 0. ); // p-y
6557 Teuchos::Array<GO> indices( 1, 0 );
6558
6559 for (int j = 0; j < dPhiU->at(0).size(); j++)
6560 {
6561 valDB_1 = 0.0;
6562 valDB_2 = 0.0;
6563
6564 for (int k = 0; k < dPhiU->size(); k++)
6565 {
6566 // DB
6567 valDB_1 = valDB_1 + weights->at(k) *
6568 ( phiP->at(k).at(i) * ( -u21[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] ) );
6569 valDB_2 = valDB_2 + weights->at(k) *
6570 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][1] - u12[0][k] * dPhiTransU[k][j][0] ) );
6571 }
6572
6573 val1 = valDB_1;
6574 val2 = valDB_2;
6575
6576 val1 = absDetB * val1;
6577 val2 = absDetB * val2;
6578
6579 value1[0] = val1; // p-x
6580 value2[0] = val2; // p-y
6581
6582 glob_j = dim * map2_rep->getGlobalElement(elements2->getElement(T).getNode(j));
6583 glob_i = map1_rep->getGlobalElement(elements->getElement(T).getNode(i));
6584 indices[0] = glob_j;
6585
6586 DB->insertGlobalValues(glob_i, indices(), value1()); // p-x
6587 glob_j++;
6588 indices[0] = glob_j;
6589 DB->insertGlobalValues(glob_i, indices(), value2()); // p-y
6590 }
6591 }
6592 }
6593 if (callFillComplete)
6594 {
6595 DB->fillComplete(map2_unique, map1_unique);
6596 }
6597 }
6598 else if(dim == 3)
6599 {
6600 double val1, val2, val3;
6601 double valDB_1, valDB_2, valDB_3;
6602 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
6603
6604 // Alle diskreten Vektoren aufstellen, dabei bezeichnet Xij = X_ij,
6605 // also i-te Komponenten von X nach der j-ten Variablen abgeleitet.
6606 // Der Gradient ist bei mir wie folgt definiert: \grad(u) = [u11, u12; u21 u22] = [grad(u_1)^T; grad(u_2)^T]
6607 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
6608 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
6609 vec2D_dbl_Type u13(1, vec_dbl_Type(weights->size(), -1.));
6610 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
6611 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
6612 vec2D_dbl_Type u23(1, vec_dbl_Type(weights->size(), -1.));
6613 vec2D_dbl_Type u31(1, vec_dbl_Type(weights->size(), -1.));
6614 vec2D_dbl_Type u32(1, vec_dbl_Type(weights->size(), -1.));
6615 vec2D_dbl_Type u33(1, vec_dbl_Type(weights->size(), -1.));
6616
6617 for (int T = 0; T < elements->numberElements(); T++)
6618 {
6619 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6620 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6621 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6622 p4 = pointsRep->at(elements->getElement(T).getNode(3));
6623
6624 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B);
6625 detB = B.computeInverse(Binv);
6626 absDetB = std::fabs(detB);
6627
6628 // dPhiTrans sind die transformierten Basifunktionen, also \grad_phi * B^(-T)
6629 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
6630 applyBTinv( dPhiU, dPhiTransU, Binv ); //dPhiTrans berechnen
6631
6632 // Diskrete Grad-Vektoren berechnen,
6633 // wobei z.B. w_ij = \frac{\partial w_i}{\partial x_j} ist.
6634 for(int k = 0; k < dPhiTransU.size(); k++) // Quadraturpunkte
6635 {
6636 u11[0][k] = 0.0;
6637 u12[0][k] = 0.0;
6638 u13[0][k] = 0.0;
6639 u21[0][k] = 0.0;
6640 u22[0][k] = 0.0;
6641 u23[0][k] = 0.0;
6642 u31[0][k] = 0.0;
6643 u32[0][k] = 0.0;
6644 u33[0][k] = 0.0;
6645
6646 for(int i = 0; i < dPhiTransU[0].size(); i++)
6647 {
6648 LO index1 = dim * elements2->getElement(T).getNode(i) + 0; // x
6649 LO index2 = dim * elements2->getElement(T).getNode(i) + 1; // y
6650 LO index3 = dim * elements2->getElement(T).getNode(i) + 2; // z
6651 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
6652 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
6653 u13[0][k] += uArray[index1] * dPhiTransU[k][i][2];
6654 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
6655 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
6656 u23[0][k] += uArray[index2] * dPhiTransU[k][i][2];
6657 u31[0][k] += uArray[index3] * dPhiTransU[k][i][0];
6658 u32[0][k] += uArray[index3] * dPhiTransU[k][i][1];
6659 u33[0][k] += uArray[index3] * dPhiTransU[k][i][2];
6660 }
6661 }
6662
6663 for (int i = 0; i < phiP->at(0).size(); i++)
6664 {
6665 Teuchos::Array<SC> value1( 1, 0. ); // p-x
6666 Teuchos::Array<SC> value2( 1, 0. ); // p-y
6667 Teuchos::Array<SC> value3( 1, 0. ); // p-z
6668 Teuchos::Array<GO> indices( 1, 0 );
6669
6670 for (int j = 0; j < dPhiU->at(0).size(); j++)
6671 {
6672 valDB_1 = 0.0;
6673 valDB_2 = 0.0;
6674 valDB_3 = 0.0;
6675
6676 for (int k = 0; k < dPhiU->size(); k++)
6677 {
6678 // DB
6679 valDB_1 = valDB_1 + weights->at(k) *
6680 ( phiP->at(k).at(i) * ( -u21[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] -
6681 u31[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][0] ) );
6682 valDB_2 = valDB_2 + weights->at(k) *
6683 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][1] - u12[0][k] * dPhiTransU[k][j][0] -
6684 u32[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][1] ) );
6685 valDB_3 = valDB_3 + weights->at(k) *
6686 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][2] - u13[0][k] * dPhiTransU[k][j][0] +
6687 u22[0][k] * dPhiTransU[k][j][2] - u23[0][k] * dPhiTransU[k][j][1] ) );
6688 }
6689
6690 val1 = valDB_1;
6691 val2 = valDB_2;
6692 val3 = valDB_3;
6693
6694 val1 = absDetB * val1;
6695 val2 = absDetB * val2;
6696 val3 = absDetB * val3;
6697
6698 value1[0] = val1; // p-x
6699 value2[0] = val2; // p-y
6700 value3[0] = val3; // p-z
6701
6702 glob_j = dim * map2_rep->getGlobalElement(elements2->getElement(T).getNode(j));
6703 glob_i = map1_rep->getGlobalElement(elements->getElement(T).getNode(i));
6704 indices[0] = glob_j;
6705
6706 DB->insertGlobalValues(glob_i, indices(), value1()); // p-x
6707 glob_j++;
6708 indices[0] = glob_j;
6709 DB->insertGlobalValues(glob_i, indices(), value2()); // p-y
6710 glob_j++;
6711 indices[0] = glob_j;
6712 DB->insertGlobalValues(glob_i, indices(), value3()); // p-z
6713 }
6714 }
6715 }
6716 if (callFillComplete)
6717 {
6718 DB->fillComplete(map2_unique, map1_unique);
6719 }
6720 }
6721
6722}
6723
6724template <class SC, class LO, class GO, class NO>
6725void FE<SC,LO,GO,NO>::assemblySurfaceIntegralExternal(int dim,
6726 std::string FEType,
6727 MultiVectorPtr_Type f,
6728 MultiVectorPtr_Type d_rep,
6729 std::vector<SC>& funcParameter,
6730 RhsFunc_Type func,
6731 ParameterListPtr_Type params,
6732 int FEloc) {
6733
6734 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
6735
6736 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
6737
6738 SC elScaling;
6739 SmallMatrix<SC> B(dim);
6740 vec_dbl_Type b(dim);
6741 f->putScalar(0.);
6742 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
6743
6744 int flagSurface = params->sublist("Parameter Solid").get("Flag Surface",5);
6745
6746 std::vector<double> valueFunc(dim);
6747
6748 SC* paramsFunc = &(funcParameter[0]);
6749
6750 // The second last entry is a placeholder for the surface element flag. It will be set below
6751 for (UN T=0; T<elements->numberElements(); T++) {
6752 FiniteElement fe = elements->getElement( T );
6753 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
6754 for (int surface=0; surface<fe.numSubElements(); surface++) {
6755 FiniteElement feSub = subEl->getElement( surface );
6756 if(subEl->getDimension() == dim-1 ){
6757
6758 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
6759
6760
6761 vec_dbl_Type solution_d = getSolution(nodeList, d_rep,dim);
6762 vec2D_dbl_Type nodes;
6763 nodes = getCoordinates(nodeList, pointsRep);
6764
6765
6766 double positions[18];
6767 int count =0;
6768 for(int i=0;i<6;i++)
6769 for(int j=0;j<3;j++){
6770 positions[count] = nodes[i][j];
6771 count++;
6772
6773 }
6774
6775
6776 paramsFunc[ funcParameter.size() - 1 ] = feSub.getFlag();
6777 vec_dbl_Type p1 = {0.,0.,0.}; // Dummy vector
6778 func( &p1[0], &valueFunc[0], paramsFunc);
6779
6780 if(valueFunc[0] != 0.){
6781
6782 double *residuumVector;
6783 #ifdef FEDD_HAVE_ACEGENINTERFACE
6784
6785 AceGenInterface::PressureTriangle3D6 pt(valueFunc[0], 1., 35, &positions[0], &solution_d[0]);
6786 pt.computeTangentResidual();
6787 residuumVector = pt.getResiduum();
6788 #endif
6789
6790 for(int i=0; i< nodeList.size() ; i++){
6791 for(int d=0; d<dim; d++)
6792 valuesF[nodeList[i]*dim+d] += residuumVector[i*dim+d];
6793 }
6794
6795 // free(residuumVector);
6796 }
6797
6798 }
6799 }
6800 }
6801 //f->scale(-1.);
6802
6803}
6804
6807
6808template <class SC, class LO, class GO, class NO>
6810 std::string FEType,
6811 MultiVectorPtr_Type f,
6812 MultiVectorPtr_Type d_rep,
6813 MatrixPtr_Type &Kext,
6814 std::vector<SC>& funcParameter,
6815 RhsFunc_Type func,
6816 ParameterListPtr_Type params,
6817 int FEloc) {
6818
6819 // degree of function funcParameter[0]
6820
6821 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
6822
6823 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
6824
6825 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
6826 SC elScaling;
6827 SmallMatrix<SC> B(dim);
6828 vec_dbl_Type b(dim);
6829 f->putScalar(0.);
6830 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
6831
6832 std::vector<double> valueFunc(dim);
6833
6834 SC* paramsFunc = &(funcParameter[0]);
6835
6836 // The second last entry is a placeholder for the surface element flag. It will be set below
6837 for (UN T=0; T<elements->numberElements(); T++) {
6838 FiniteElement fe = elements->getElement( T );
6839 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
6840 for (int surface=0; surface<fe.numSubElements(); surface++) {
6841 FiniteElement feSub = subEl->getElement( surface );
6842 if(subEl->getDimension() == dim-1 ){
6843 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
6844
6845 vec_dbl_Type solution_d = getSolution(nodeList, d_rep,dim);
6846 vec2D_dbl_Type nodes;
6847 nodes = getCoordinates(nodeList, pointsRep);
6848
6849
6850 double positions[18];
6851 int count =0;
6852 for(int i=0;i<6;i++){
6853 for(int j=0;j<3;j++){
6854 positions[count] = nodes[i][j];
6855 count++;
6856
6857 }
6858 }
6859
6860 vec_dbl_Type p1 = {0.,0.,0.}; // Dummy vector
6861 paramsFunc[ funcParameter.size() - 1 ] = feSub.getFlag();
6862 func( &p1[0], &valueFunc[0], paramsFunc);
6863
6864 if(valueFunc[0] != 0.){
6865
6866 double *residuumVector;
6867 double **stiffMat;
6868
6869 #ifdef FEDD_HAVE_ACEGENINTERFACE
6870 AceGenInterface::PressureTriangle3D6 pt(valueFunc[0], 1.0, 35, &positions[0], &solution_d[0]);
6871 pt.computeTangentResidual();
6872
6873 residuumVector = pt.getResiduum();
6874 stiffMat = pt.getStiffnessMatrix();
6875 #endif
6876
6877
6878
6879 int dofs1 = dim;
6880 int numNodes1 =nodeList.size();
6881
6882 SmallMatrix_Type elementMatrixPrint(18,0.);
6883 for(int i=0; i< 18 ; i++){
6884 for(int j=0; j< 18; j++){
6885 if(std::fabs(stiffMat[i][j]) >1e-13)
6886 elementMatrixPrint[i][j] = stiffMat[i][j];
6887
6888 }
6889 }
6890
6891 SmallMatrix_Type elementMatrixWrite(18,0.);
6892
6893 SmallMatrix_Type elementMatrixIDsRow(18,0.);
6894 SmallMatrix_Type elementMatrixIDsCol(18,0.);
6895
6896
6897 for (UN i=0; i < numNodes1 ; i++) {
6898 for(int di=0; di<dim; di++){
6899 Teuchos::Array<SC> value1( numNodes1*dim, 0. );
6900 Teuchos::Array<GO> columnIndices1( numNodes1*dim, 0 );
6901 GO row =GO (dim* map->getGlobalElement( nodeList[i] )+di);
6902 LO rowLO = dim*i+di;
6903 // Zeilenweise werden die Einträge global assembliert
6904 for (UN j=0; j <numNodes1; j++){
6905 for(int d=0; d<dim; d++){
6906 columnIndices1[dim*j+d] = GO ( dim * map->getGlobalElement( nodeList[j] ) + d );
6907 value1[dim*j+d] = stiffMat[rowLO][dim*j+d];
6908 }
6909 }
6910 Kext->insertGlobalValues( row, columnIndices1(), value1() ); // Automatically adds entries if a value already exists
6911 }
6912 }
6913
6914
6915
6916 for(int i=0; i< nodeList.size() ; i++){
6917 for(int d=0; d<dim; d++){
6918 valuesF[nodeList[i]*dim+d] += residuumVector[i*dim+d];
6919 }
6920 }
6921
6922
6923 }
6924
6925
6926 }
6927 }
6928 }
6929 //f->scale(-1.);
6930 Kext->fillComplete(domainVec_.at(FEloc)->getMapVecFieldUnique(),domainVec_.at(FEloc)->getMapVecFieldUnique());
6931 // Kext->writeMM("K_ext1");
6932}
6933
6935template <class SC, class LO, class GO, class NO>
6936void FE<SC,LO,GO,NO>::computeSurfaceNormal(int dim,
6937 vec2D_dbl_ptr_Type pointsRep,
6938 vec_int_Type nodeList,
6939 vec_dbl_Type &v_E,
6940 double &norm_v_E)
6941{
6942
6943 vec_dbl_Type p1(dim),p2(dim);
6944
6945 if(dim==2){
6946 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
6947 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
6948 norm_v_E = std::sqrt(std::pow(v_E[0],2)+std::pow(v_E[1],2));
6949
6950 }
6951 else if(dim==3){
6952
6953 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
6954 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
6955 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
6956
6957 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
6958 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
6959 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
6960
6961 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
6962 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
6963 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
6964
6965 norm_v_E = std::sqrt(std::pow(v_E[0],2)+std::pow(v_E[1],2)+std::pow(v_E[2],2));
6966
6967 }
6968
6969}
6970
6971template <class SC, class LO, class GO, class NO>
6972void FE<SC,LO,GO,NO>::assemblySurfaceIntegral(int dim,
6973 std::string FEType,
6974 MultiVectorPtr_Type f,
6975 std::string fieldType,
6976 RhsFunc_Type func,
6977 std::vector<SC>& funcParameter) {
6978
6979 // degree of function funcParameter[0]
6980 //TEUCHOS_TEST_FOR_EXCEPTION( funcParameter[funcParameter.size()-1] > 0., std::logic_error, "We only support constant functions for now.");
6981 UN FEloc = checkFE(dim,FEType);
6982
6983 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
6984
6985 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
6986
6987 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
6988 vec2D_dbl_ptr_Type phi;
6989 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
6990
6991 UN degFunc = funcParameter[funcParameter.size()-1] + 1.e-14; // Degree from function set/determined externally
6992 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0) + degFunc;
6993
6994 Helper::getPhi(phi, weights, dim-1, FEType, deg);
6995
6996 vec2D_dbl_ptr_Type quadPoints;
6997 vec_dbl_ptr_Type w = Teuchos::rcp(new vec_dbl_Type(0));
6998 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
6999 w.reset();
7000
7001 SC elScaling;
7002 SmallMatrix<SC> B(dim);
7003 vec_dbl_Type b(dim);
7004 f->putScalar(0.);
7005 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
7006 int parameters;
7007
7008
7009 std::vector<double> valueFunc(dim);
7010 // The second last entry is a placeholder for the surface element flag. It will be set below
7011 SC* params = &(funcParameter[0]);
7012 for (UN T=0; T<elements->numberElements(); T++) {
7013 FiniteElement fe = elements->getElement( T );
7014 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
7015 for (int surface=0; surface<fe.numSubElements(); surface++) {
7016 FiniteElement feSub = subEl->getElement( surface );
7017 if(subEl->getDimension() == dim-1){
7018 // Setting flag to the placeholder (second last entry). The last entry at (funcParameter.size() - 1) should always be the degree of the surface function
7019 params[ funcParameter.size() - 1 ] = feSub.getFlag();
7020
7021 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
7022
7023 vec_dbl_Type v_E(dim,1.);
7024 double norm_v_E=1.;
7025
7026 Helper::computeSurfaceNormal(dim, pointsRep,nodeList,v_E,norm_v_E);
7027
7028 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
7029 elScaling = B.computeScaling( );
7030 // loop over basis functions
7031 for (UN i=0; i < phi->at(0).size(); i++) {
7032 Teuchos::Array<SC> value(0);
7033 if ( fieldType == "Scalar" )
7034 value.resize( 1, 0. );
7035 else if ( fieldType == "Vector" )
7036 value.resize( dim, 0. );
7037 // loop over basis functions quadrature points
7038 for (UN w=0; w<phi->size(); w++) {
7039 vec_dbl_Type x(dim,0.); //coordinates
7040 for (int k=0; k<dim; k++) {// transform quad points to global coordinates
7041 for (int l=0; l<dim-1; l++){
7042 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ];
7043 }
7044 x[k] += b[k];
7045 }
7046
7047 func( &x[0], &valueFunc[0], params);
7048 if ( fieldType == "Scalar" )
7049 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
7050 else if ( fieldType == "Vector" ){
7051 for (int j=0; j<value.size(); j++){
7052 value[j] += weights->at(w) * valueFunc[j]*v_E[j]/norm_v_E * (*phi)[w][i];
7053 }
7054 }
7055 }
7056
7057 for (int j=0; j<value.size(); j++)
7058 value[j] *= elScaling;
7059
7060 if ( fieldType== "Scalar" )
7061 valuesF[ nodeList[ i ] ] += value[0];
7062
7063
7064 else if ( fieldType== "Vector" ){
7065 for (int j=0; j<value.size(); j++)
7066 valuesF[ dim * nodeList[ i ] + j ] += value[j];
7067 }
7068 }
7069 }
7070 }
7071 }
7072 f->scale(-1.); // Generally the pressure is definied in opposite direction of the normal
7073}
7074
7075template <class SC, class LO, class GO, class NO>
7076void FE<SC,LO,GO,NO>::assemblySurfaceIntegralFlag(int dim,
7077 std::string FEType,
7078 MultiVectorPtr_Type f,
7079 std::string fieldType,
7080 BC_func_Type func,
7081 std::vector<SC>& funcParameter) {
7082
7083// degree of function funcParameter[0]
7084 TEUCHOS_TEST_FOR_EXCEPTION(funcParameter[0]!=0,std::logic_error, "We only support constant functions for now.");
7085
7086 UN FEloc = checkFE(dim,FEType);
7087
7088 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
7089
7090 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
7091
7092 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
7093 vec2D_dbl_ptr_Type phi;
7094 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
7095 UN degFunc = funcParameter[0] + 1.e-14;
7096 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0) + degFunc;
7097
7098 Helper::getPhi(phi, weights, dim-1, FEType, deg);
7099
7100 vec2D_dbl_ptr_Type quadPoints;
7101 vec_dbl_ptr_Type w = Teuchos::rcp(new vec_dbl_Type(0));
7102 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
7103 w.reset();
7104
7105 SC elScaling;
7106 SmallMatrix<SC> B(dim);
7107 vec_dbl_Type b(dim);
7108 f->putScalar(0.);
7109 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
7110 int parameters;
7111
7112 std::vector<double> valueFunc(dim);
7113 SC* params = &(funcParameter[1]);
7114 for (UN T=0; T<elements->numberElements(); T++) {
7115 FiniteElement fe = elements->getElement( T );
7116 ElementsPtr_Type subEl = fe.getSubElements(); // might be null
7117 for (int surface=0; surface<fe.numSubElements(); surface++) {
7118 FiniteElement feSub = subEl->getElement( surface );
7119 if (params[1] == feSub.getFlag()){
7120 FiniteElement feSub = subEl->getElement( surface );
7121 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
7122 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
7123 elScaling = B.computeScaling( );
7124 // loop over basis functions
7125 for (UN i=0; i < phi->at(0).size(); i++) {
7126 Teuchos::Array<SC> value(0);
7127 if ( fieldType == "Scalar" )
7128 value.resize( 1, 0. );
7129 else if ( fieldType == "Vector" )
7130 value.resize( dim, 0. );
7131 // loop over basis functions quadrature points
7132 for (UN w=0; w<phi->size(); w++) {
7133 vec_dbl_Type x(dim,0.); //coordinates
7134 for (int k=0; k<dim; k++) {// transform quad points to global coordinates
7135 for (int l=0; l<dim-1; l++)
7136 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ];
7137 x[k] += b[k];
7138 }
7139
7140 func( &x[0], &valueFunc[0], params[0], params);
7141// func( &x[0], &valueFunc[0], params);
7142 if ( fieldType == "Scalar" )
7143 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
7144 else if ( fieldType == "Vector" ){
7145 for (int j=0; j<value.size(); j++){
7146 value[j] += weights->at(w) * valueFunc[j] * (*phi)[w][i];
7147 }
7148 }
7149 }
7150
7151 for (int j=0; j<value.size(); j++)
7152 value[j] *= elScaling;
7153
7154 if ( fieldType== "Scalar" )
7155 valuesF[ nodeList[ i ] ] += value[0];
7156
7157
7158 else if ( fieldType== "Vector" ){
7159 for (int j=0; j<value.size(); j++)
7160 valuesF[ dim * nodeList[ i ] + j ] += value[j];
7161 }
7162 }
7163 }
7164 }
7165
7166 }
7167}
7168
7169template <class SC, class LO, class GO, class NO>
7170void FE<SC,LO,GO,NO>::assemblyRHS( int dim,
7171 std::string FEType,
7172 MultiVectorPtr_Type a,
7173 std::string fieldType,
7174 RhsFunc_Type func,
7175 std::vector<SC>& funcParameter
7176 ) {
7177
7178 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
7179
7180 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error, "MultiVector in assemblyConstRHS is null." );
7181 TEUCHOS_TEST_FOR_EXCEPTION( a->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
7182 UN FEloc;
7183 FEloc = checkFE(dim,FEType);
7184
7185 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
7186
7187 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
7188
7189 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
7190 vec2D_dbl_ptr_Type phi;
7191 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
7192
7193 // last parameter should alwayss be the degree
7194 //UN degFunc = funcParameter[funcParameter.size()-1] + 1.e-14; // TODO: [JK] Can we remove this?
7195 // inner( f(x), phi(x) ) requires the integration degree of the basis function + some
7196 // extra user-provided degree that accounts for the heterogeneity of f(x).
7197 UN degFunc = 2; // TODO: [JK] Hard coded for now, but needs to be passed by the user. See GitHub issue #66.
7198 UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv0) + degFunc;
7199
7200 vec2D_dbl_ptr_Type quadPoints;
7201 Helper::getQuadratureValues(dim, deg, quadPoints, weights, FEType); // quad points for rhs values
7202
7203
7204 Helper::getPhi(phi, weights, dim, FEType, deg);
7205
7206 SC detB;
7207 SC absDetB;
7208 SmallMatrix<SC> B(dim);
7209 GO glob_i, glob_j;
7210 vec_dbl_Type v_i(dim);
7211 vec_dbl_Type v_j(dim);
7212
7213 Teuchos::ArrayRCP< SC > valuesRhs = a->getDataNonConst(0);
7214 int parameters;
7215 double x;
7216 //for now just const!
7217 std::vector<double> valueFunc(dim);
7218 SC* paras = &(funcParameter[0]);
7219
7220 func( &x, &valueFunc[0], paras );
7221 SC value;
7222
7223 for (UN T=0; T<elements->numberElements(); T++) {
7224
7225 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
7226 detB = B.computeDet( );
7227 absDetB = std::fabs(detB);
7228
7229 vec2D_dbl_Type quadPointsTrans(weights->size(),vec_dbl_Type(dim));
7230 for(int i=0; i< weights->size(); i++){
7231 for(int j=0; j< dim ; j++){
7232 for(int k=0; k< dim; k++){
7233 quadPointsTrans[i][j] += B[j][k]* quadPoints->at(i).at(k) ;
7234 }
7235 quadPointsTrans[i][j] += pointsRep->at(elements->getElement(T).getNode(0)).at(j);
7236 }
7237 }
7238 for (UN i=0; i < phi->at(0).size(); i++) {
7239 if ( !fieldType.compare("Scalar") ) {
7240 value = Teuchos::ScalarTraits<SC>::zero();
7241 for (UN w=0; w<weights->size(); w++){
7242 func(&quadPointsTrans[w][0], &valueFunc[0] ,paras);
7243 value += weights->at(w) * phi->at(w).at(i)*valueFunc[0];
7244 }
7245 value *= absDetB;
7246 LO row = (LO) elements->getElement(T).getNode(i);
7247 valuesRhs[row] += value;
7248 }
7249 else if( !fieldType.compare("Vector") ) {
7250 for (UN d=0; d<dim; d++) {
7251 value = Teuchos::ScalarTraits<SC>::zero();
7252 for (UN w=0; w<weights->size(); w++){
7253 func(&quadPointsTrans[w][0], &valueFunc[0] ,paras);
7254 value += weights->at(w) * phi->at(w).at(i)*valueFunc[d];
7255 }
7256 value *= absDetB;
7257 SC v_i = value;
7258 LO row = (LO) ( dim * elements->getElement(T).getNode(i) + d );
7259 valuesRhs[row] += v_i;
7260 }
7261 }
7262 else
7263 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Invalid field type." );
7264 }
7265 }
7266}
7267
7272template <class SC, class LO, class GO, class NO>
7274 std::string FEType,
7275 MatrixPtr_Type a,
7276 MatrixPtr_Type aT)
7277 {
7278
7279 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
7280
7281 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error, "Matrix is null." );
7282
7283 UN FEloc;
7284 FEloc = checkFE(dim,FEType);
7285
7286 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
7287
7288 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
7289
7290 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
7291 vec2D_dbl_ptr_Type phi;
7292 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
7293 // last parameter should alwayss be the degree
7294 UN deg = 2;
7295
7296 vec2D_dbl_ptr_Type quadPoints;
7297 Helper::getQuadratureValues(dim, deg, quadPoints, weights, FEType); // quad points for rhs values
7298
7299 Helper::getPhi(phi, weights, dim, FEType, deg);
7300
7301 SC detB;
7302 SC absDetB;
7303 SmallMatrix<SC> B(dim);
7304 GO glob_i, glob_j;
7305 vec_dbl_Type v_i(dim);
7306 vec_dbl_Type v_j(dim);
7307
7308
7309 for (UN T=0; T<elements->numberElements(); T++) {
7310
7311 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
7312 detB = B.computeDet( );
7313 absDetB = std::fabs(detB);
7314
7315 for (UN i=0; i < phi->at(0).size(); i++) {
7316 Teuchos::Array<SC> value( 1, 0. );
7317 for (UN w=0; w<weights->size(); w++){
7318 value[0] += weights->at(w) * phi->at(w).at(i)*1.0;
7319 }
7320 value[0] *= absDetB;
7321 LO row = (LO) elements->getElement(T).getNode(i);
7322 Teuchos::Array<GO> columnIndices( 1, 0 ); // We only have on column
7323
7324 a->insertGlobalValues( row, columnIndices(), value() ); // Automatically adds entries if a value already exists
7325 columnIndices[0] = row;
7326 aT->insertGlobalValues( 0, columnIndices(), value() ); // Automatically adds entries if a value already exists
7327 }
7328 }
7329 a->fillComplete();
7330 //a->print();
7331
7332}
7333
7334
7335template <class SC, class LO, class GO, class NO>
7336void FE<SC,LO,GO,NO>::assemblyRHSDegTest( int dim,
7337 std::string FEType,
7338 MultiVectorPtr_Type a,
7339 std::string fieldType,
7340 RhsFunc_Type func,
7341 std::vector<SC>& funcParameter,
7342 int degree) {
7343 // TODO: [JK] What is the aim of this function? It is not called by any problems, only by a test.
7344 TEUCHOS_TEST_FOR_EXCEPTION(FEType == "P0",std::logic_error, "Not implemented for P0");
7345
7346 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error, "MultiVector in assemblyConstRHS is null." );
7347 TEUCHOS_TEST_FOR_EXCEPTION( a->getNumVectors()>1, std::logic_error, "Implement for numberMV > 1 ." );
7348
7349 UN FEloc = checkFE(dim,FEType);
7350
7351 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
7352
7353 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
7354
7355 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
7356 vec2D_dbl_ptr_Type phi;
7357 vec_dbl_ptr_Type weights = Teuchos::rcp(new vec_dbl_Type(0));
7358 Helper::getPhi(phi, weights, dim, FEType, degree);
7359
7360 vec2D_dbl_ptr_Type quadPoints;
7361 vec_dbl_ptr_Type w = Teuchos::rcp(new vec_dbl_Type(0));
7362 Helper::getQuadratureValues(dim, degree, quadPoints, w, FEType);
7363 w.reset();
7364
7365
7366 SC detB;
7367 SC absDetB;
7368 SmallMatrix<SC> B(dim);
7369 vec_dbl_Type b(dim);
7370 GO glob_i, glob_j;
7371 vec_dbl_Type v_i(dim);
7372 vec_dbl_Type v_j(dim);
7373
7374 Teuchos::ArrayRCP< SC > valuesRhs = a->getDataNonConst(0);
7375 int parameters;
7376 double x;
7377 //for now just const!
7378 std::vector<double> valueFunc(dim);
7379 SC* params = &(funcParameter[1]);
7380 for (UN T=0; T<elements->numberElements(); T++) {
7381
7382 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, b, FEType);
7383 detB = B.computeDet( );
7384 absDetB = std::fabs(detB);
7385
7386 for (UN i=0; i < phi->at(0).size(); i++) {
7387 Teuchos::Array<SC> value(1);
7388 for (UN w=0; w<weights->size(); w++){
7389 vec_dbl_Type x(dim,0.); //coordinates
7390 for (int k=0; k<dim; k++) {// transform quad points to global coordinates
7391 for (int l=0; l<dim; l++)
7392 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ] + b[k];
7393 }
7394
7395 func( &x[0], &valueFunc[0], params);
7396 if ( !fieldType.compare("Scalar") ) {
7397 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
7398 }
7399 else if( !fieldType.compare("Vector") ) {
7400 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "No test for field type Vector." );
7401 }
7402 else
7403 TEUCHOS_TEST_FOR_EXCEPTION( true, std::logic_error, "Invalid field type." );
7404
7405 }
7406 value[0] *= absDetB;
7407 LO row = (LO) elements->getElement(T).getNode(i);
7408 valuesRhs[row] += value[0];
7409
7410 }
7411 }
7412}
7413
7414
7415template <class SC, class LO, class GO, class NO>
7416void FE<SC,LO,GO,NO>::buildFullDPhi(vec3D_dbl_ptr_Type dPhi, Teuchos::Array<SmallMatrix<double> >& dPhiMat){
7417
7418 TEUCHOS_TEST_FOR_EXCEPTION(dPhi->size()*dPhi->at(0).size()*dPhi->at(0).at(0).size() != dPhiMat.size(), std::logic_error, "Wrong sizes for dPhi and dPhiMat.");
7419
7420 int dim = dPhi->at(0).at(0).size();
7421 int nmbBasisFunc = dPhi->at(0).size();
7422 int nmbTotalBasisFunc = nmbBasisFunc * dim;
7423 if (dim==2) {
7424 for (int p=0; p<dPhi->size(); p++) { //loop over quad points
7425 for (int i=0; i<nmbBasisFunc; i++) { //loop over basis functions
7426 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][0] = dPhi->at(p).at(i).at(0);
7427 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][1] = dPhi->at(p).at(i).at(1);
7428 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][0] = 0.;
7429 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][1] = 0.;
7430
7431 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][0] = 0.;
7432 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][1] = 0.;
7433 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][0] = dPhi->at(p).at(i).at(0);
7434 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][1] = dPhi->at(p).at(i).at(1);
7435 }
7436 }
7437 }
7438 else if(dim==3){
7439 for (int p=0; p<dPhi->size(); p++) { //loop over quad points
7440 for (int i=0; i<nmbBasisFunc; i++) { //loop over basis functions
7441 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][0] = dPhi->at(p).at(i).at(0);
7442 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][1] = dPhi->at(p).at(i).at(1);
7443 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][2] = dPhi->at(p).at(i).at(2);
7444 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][0] = 0.;
7445 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][1] = 0.;
7446 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][2] = 0.;
7447 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][0] = 0.;
7448 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][1] = 0.;
7449 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][2] = 0.;
7450
7451 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][0] = 0.;
7452 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][1] = 0.;
7453 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][2] = 0.;
7454 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][0] = dPhi->at(p).at(i).at(0);
7455 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][1] = dPhi->at(p).at(i).at(1);
7456 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][2] = dPhi->at(p).at(i).at(2);
7457 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][0] = 0.;
7458 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][1] = 0.;
7459 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][2] = 0.;
7460
7461 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][0] = 0.;
7462 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][1] = 0.;
7463 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][2] = 0.;
7464 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][0] = 0.;
7465 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][1] = 0.;
7466 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][2] = 0.;
7467 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][0] = dPhi->at(p).at(i).at(0);
7468 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][1] = dPhi->at(p).at(i).at(1);
7469 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][2] = dPhi->at(p).at(i).at(2);
7470 }
7471 }
7472 }
7473}
7474
7475template <class SC, class LO, class GO, class NO>
7476void FE<SC,LO,GO,NO>::fillMatrixArray(SmallMatrix<double> &matIn, double* matArrayOut, std::string order,int offset){
7477 if (!order.compare("cols")) {
7478 for (int j=0; j<matIn.size(); j++) {
7479 for (int i=0; i<matIn.size(); i++) {
7480 matArrayOut[ j * matIn.size() + i + offset ] = matIn[i][j]; //Spalten der Matrix werden hintereinander in array geschrieben
7481 }
7482 }
7483 }
7484 else if(!order.compare("rows")) {
7485 for (int i=0; i<matIn.size(); i++) {
7486 for (int j=0; j<matIn.size(); j++) {
7487 matArrayOut[ i * matIn.size() + j + offset ] = matIn[i][j]; //Zeilen der Matrix werden hintereinander in array geschrieben
7488 }
7489 }
7490 }
7491 else
7492 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "Unknown ordering for matrix to array conversion. Choose rows or cols.");
7493}
7494
7495template <class SC, class LO, class GO, class NO>
7496void FE<SC,LO,GO,NO>::epsilonTensor(vec_dbl_Type &basisValues, SmallMatrix<SC> &epsilonValues, int activeDof){
7497
7498 for (int i=0; i<epsilonValues.size(); i++) {
7499 for (int j=0; j<epsilonValues.size(); j++) {
7500 epsilonValues[i][j] = 0.;
7501 if (i==activeDof) {
7502 epsilonValues[i][j] += 0.5*basisValues.at(j);
7503 }
7504 if (j==activeDof) {
7505 epsilonValues[i][j] += 0.5*basisValues.at(i);
7506 }
7507 }
7508 }
7509}
7510
7511/*template <class SC, class LO, class GO, class NO>
7512void FE<SC,LO,GO,NO>::phi(int dim,
7513 int intFE,
7514 int i,
7515 vec_dbl_Type &p,
7516 double* value){
7517
7518 if (dim==1) {
7519 switch (intFE) {
7520 case 0: //P0
7521 switch (i) {
7522 case 0:
7523 *value = 1.;
7524 break;
7525 }
7526 break;
7527 case 1://P1
7528 switch (i) {
7529 case 0:
7530 *value = ( 1. - p.at(0) );
7531 break;
7532 case 1:
7533 *value = p.at(0);
7534 break;
7535 }
7536 break;
7537 case 2://P2
7538 switch (i) {
7539 case 0:
7540 *value = ( 1. - 3. * p[0] + 2. * p[0] * p[0] );
7541 break;
7542 case 1:
7543 *value = ( - p[0] + 2. * p[0] * p[0] );
7544 break;
7545 case 2:
7546 *value = ( 4. * p[0] - 4. * p[0] * p[0] );
7547 break;
7548
7549 }
7550 break;
7551 default:
7552 TEUCHOS_TEST_FOR_EXCEPTION( true, std::runtime_error, "Only P0,P1,P2 1D basis functions available." );
7553 break;
7554 }
7555 }
7556 else if (dim==2) {
7557 switch (intFE) {
7558 case 0://P0
7559 switch (i) {
7560 case 0:
7561 *value = 1.;
7562 break;
7563 }
7564 break;
7565 case 1://P1
7566 switch (i) {
7567 case 0:
7568 *value = (1. - p.at(0)-p.at(1));
7569 break;
7570 case 1:
7571 *value = p.at(0);
7572 break;
7573 case 2:
7574 *value = p.at(1);
7575 break;
7576 }
7577 break;
7578 case 2://P2
7579 switch (i) {
7580 case 0:
7581 *value = -(1. - p.at(0)-p.at(1)) * (1 - 2.*(1-p.at(0) - p.at(1)));
7582 break;
7583 case 1:
7584 *value = -p.at(0) * (1 - 2*p.at(0));
7585 break;
7586 case 2:
7587 *value = -p.at(1) * (1 - 2*p.at(1));
7588 break;
7589 case 3:
7590 *value = 4*p.at(0) * (1 - p.at(0)-p.at(1));
7591 break;
7592 case 4:
7593 *value = 4*p.at(0)*p.at(1);
7594 break;
7595 case 5:
7596 *value = 4*p.at(1) * (1 - p.at(0)-p.at(1));
7597 break;
7598 }
7599 break;
7600 }
7601 }
7602 else if(dim==3){
7603 switch (intFE) {
7604 case 1://P1
7605 switch (i) {
7606 case 0:
7607 *value = (1. - p.at(0)-p.at(1)-p.at(2));
7608 break;
7609 case 1:
7610 *value = p.at(0);
7611 break;
7612 case 2:
7613 *value = p.at(1);
7614 break;
7615 case 3:
7616 *value = p.at(2);
7617 break;
7618 }
7619 break;
7620 case 2: //P2
7621 switch (i) {
7622 case 0:
7623 *value = (1. - p.at(0)-p.at(1)-p.at(2)) * (1 - 2*p.at(0) - 2*p.at(1) - 2*p.at(2));
7624 break;
7625 case 1:
7626 *value = p.at(0) * (2*p.at(0) - 1);
7627 break;
7628 case 2:
7629 *value = p.at(1) * (2*p.at(1) - 1);
7630 break;
7631 case 3:
7632 *value = p.at(2) * (2*p.at(2) - 1);
7633 break;
7634 case 4:
7635 *value = 4*p.at(0) * (1 - p.at(0)-p.at(1)-p.at(2));
7636 break;
7637 case 5:
7638 *value = 4*p.at(0)*p.at(1);
7639 break;
7640 case 6:
7641 *value = 4*p.at(1) * (1 - p.at(0)-p.at(1)-p.at(2));
7642 break;
7643 case 7:
7644 *value = 4*p.at(2) * (1 - p.at(0)-p.at(1)-p.at(2));
7645 break;
7646 case 8:
7647 *value = 4*p.at(0)*p.at(2);
7648 break;
7649 case 9:
7650 *value = 4*p.at(1)*p.at(2);
7651 break;
7652 }
7653 break;
7654 case 3: //Q1
7655 {
7656 double a = 1./8;
7657 switch (i) {
7658 case 0:
7659 *value = a * ( 1 - p[0] ) * ( 1 - p[1] ) * ( 1 - p[2] );
7660 break;
7661 case 1:
7662 *value = a * ( 1 + p[0] ) * ( 1 - p[1] ) * ( 1 - p[2] );
7663 break;
7664 case 2:
7665 *value = a * ( 1 + p[0] ) * ( 1 + p[1] ) * ( 1 - p[2] );
7666 break;
7667 case 3:
7668 *value = a * ( 1 - p[0] ) * ( 1 + p[1] ) * ( 1 - p[2] );
7669 break;
7670 case 4:
7671 *value = a * ( 1 - p[0] ) * ( 1 - p[1] ) * ( 1 + p[2] );
7672 break;
7673 case 5:
7674 *value = a * ( 1 + p[0] ) * ( 1 - p[1] ) * ( 1 + p[2] );
7675 break;
7676 case 6:
7677 *value = a * ( 1 + p[0] ) * ( 1 + p[1] ) * ( 1 + p[2] );
7678 break;
7679 case 7:
7680 *value = a * ( 1 - p[0] ) * ( 1 + p[1] ) * ( 1 + p[2] );
7681 break;
7682 default:
7683 break;
7684 }
7685 break;
7686 }
7687 case 4: //Q2
7688 {
7689 double a = 1./8;
7690 double b = 1./4;
7691 double c = 1./2;
7692 switch (i) {
7693 case 0:
7694 *value = 0.125*p[0]*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7695 break;
7696 case 1:
7697 *value = 0.125*p[0]*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7698 break;
7699 case 2:
7700 *value = -0.125*p[0]*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7701 break;
7702 case 3:
7703 *value = -0.125*p[0]*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7704 break;
7705 case 4:
7706 *value = -0.125*p[0]*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7707 break;
7708 case 5:
7709 *value = -0.125*p[0]*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7710 break;
7711 case 6:
7712 *value = 0.125*p[0]*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7713 break;
7714 case 7:
7715 *value = 0.125*p[0]*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[1]*p[2] + 0.125*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7716 break;
7717 case 8:
7718 *value = 0.250*p[1]*p[2] + -0.250*p[1]*p[1]*p[2] + -0.250*p[2]*p[2]*p[1] + -0.250*p[0]*p[0]*p[1]*p[2] + 0.250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7719 break;
7720 case 9:
7721 *value = -0.250*p[0]*p[2] + -0.250*p[0]*p[0]*p[2] + 0.250*p[2]*p[2]*p[0] + 0.250*p[1]*p[1]*p[0]*p[2] + 0.250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7722 break;
7723 case 10:
7724 *value = -0.250*p[1]*p[2] + -0.250*p[1]*p[1]*p[2] + 0.250*p[2]*p[2]*p[1] + 0.250*p[0]*p[0]*p[1]*p[2] + 0.250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7725 break;
7726 case 11:
7727 *value = 0.250*p[0]*p[2] + -0.250*p[0]*p[0]*p[2] + -0.250*p[2]*p[2]*p[0] + -0.250*p[1]*p[1]*p[0]*p[2] + 0.250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7728 break;
7729 case 12:
7730 *value = -0.250*p[1]*p[2] + 0.250*p[1]*p[1]*p[2] + -0.250*p[2]*p[2]*p[1] + 0.250*p[0]*p[0]*p[1]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7731 break;
7732 case 13:
7733 *value = 0.250*p[0]*p[2] + 0.250*p[0]*p[0]*p[2] + 0.250*p[2]*p[2]*p[0] + -0.250*p[1]*p[1]*p[0]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7734 break;
7735 case 14:
7736 *value = 0.250*p[1]*p[2] + 0.250*p[1]*p[1]*p[2] + 0.250*p[2]*p[2]*p[1] + -0.250*p[0]*p[0]*p[1]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7737 break;
7738 case 15:
7739 *value = -0.250*p[0]*p[2] + 0.250*p[0]*p[0]*p[2] + -0.250*p[2]*p[2]*p[0] + 0.250*p[1]*p[1]*p[0]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7740 break;
7741 case 16:
7742 *value = 0.250*p[0]*p[1] + -0.250*p[0]*p[0]*p[1] + -0.250*p[1]*p[1]*p[0] + -0.250*p[2]*p[2]*p[0]*p[1] + 0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7743 break;
7744 case 17:
7745 *value = -0.250*p[0]*p[1] + -0.250*p[0]*p[0]*p[1] + 0.250*p[1]*p[1]*p[0] + 0.250*p[2]*p[2]*p[0]*p[1] + 0.250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7746 break;
7747 case 18:
7748 *value =0.250*p[0]*p[1] + 0.250*p[0]*p[0]*p[1] + 0.250*p[1]*p[1]*p[0] + -0.250*p[2]*p[2]*p[0]*p[1] + -0.250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7749 break;
7750 case 19:
7751 *value = -0.250*p[0]*p[1] + 0.250*p[0]*p[0]*p[1] + -0.250*p[1]*p[1]*p[0] + 0.250*p[2]*p[2]*p[0]*p[1] + -0.250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7752 break;
7753 case 20:
7754 *value = -0.500*p[1] + 0.500*p[1]*p[1] + 0.500*p[0]*p[0]*p[1] + 0.500*p[2]*p[2]*p[1] + -0.500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[1]*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7755 break;
7756 case 21:
7757 *value = 0.500*p[0] + 0.500*p[0]*p[0] + -0.500*p[1]*p[1]*p[0] + -0.500*p[2]*p[2]*p[0] + 0.500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[0]*p[0]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7758 break;
7759 case 22:
7760 *value = 0.500*p[1] + 0.500*p[1]*p[1] + -0.500*p[0]*p[0]*p[1] + -0.500*p[2]*p[2]*p[1] + 0.500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[1]*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7761 break;
7762 case 23:
7763 *value = -0.500*p[0] + 0.500*p[0]*p[0] + 0.500*p[1]*p[1]*p[0] + 0.500*p[2]*p[2]*p[0] + -0.500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[0]*p[0]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7764 break;
7765 case 24:
7766 *value = -0.500*p[2] + 0.500*p[2]*p[2] + 0.500*p[0]*p[0]*p[2] + 0.500*p[1]*p[1]*p[2] + -0.500*p[0]*p[0]*p[1]*p[1]*p[2] + -0.500*p[0]*p[0]*p[2]*p[2] + -0.500*p[1]*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7767 break;
7768 case 25:
7769 *value = 1.000 + -1.000*p[0]*p[0] + -1.000*p[1]*p[1] + -1.000*p[2]*p[2] + 1.000*p[0]*p[0]*p[1]*p[1] + 1.000*p[0]*p[0]*p[2]*p[2] + 1.000*p[1]*p[1]*p[2]*p[2] + -1.000*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7770 break;
7771 case 26:
7772 *value = 0.500*p[2] + 0.500*p[2]*p[2] + -0.500*p[0]*p[0]*p[2] + -0.500*p[1]*p[1]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2] + -0.500*p[0]*p[0]*p[2]*p[2] + -0.500*p[1]*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*p[2]*p[2];
7773 break;
7774 default:
7775 break;
7776 }
7777 break;
7778 }
7779 case 5: //Q2-20
7780 {
7781 switch (i) {
7782 case 0:
7783 *value = -0.0625 + 0.1250*p[0]*p[0]*p[1]*p[2] + 0.1250*p[1]*p[1]*p[0]*p[2] + 0.1250*p[2]*p[2]*p[0]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + -0.1250*p[0]*p[1]*p[2];
7784
7785 break;
7786 case 1:
7787 *value = -0.0625 + 0.1250*p[0]*p[0]*p[1]*p[2] + -0.1250*p[1]*p[1]*p[0]*p[2] + -0.1250*p[2]*p[2]*p[0]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + 0.1250*p[0]*p[1]*p[2];
7788
7789
7790
7791 break;
7792 case 2:
7793 *value = -0.0625 + -0.1250*p[0]*p[0]*p[1]*p[2] + -0.1250*p[1]*p[1]*p[0]*p[2] + 0.1250*p[2]*p[2]*p[0]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + -0.1250*p[0]*p[1]*p[2];
7794
7795
7796
7797 break;
7798 case 3:
7799 *value = -0.0625 + -0.1250*p[0]*p[0]*p[1]*p[2] + 0.1250*p[1]*p[1]*p[0]*p[2] + -0.1250*p[2]*p[2]*p[0]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + 0.1250*p[0]*p[1]*p[2];
7800
7801
7802
7803 break;
7804 case 4:
7805 *value = -0.0625 + -0.1250*p[0]*p[0]*p[1]*p[2] + -0.1250*p[1]*p[1]*p[0]*p[2] + 0.1250*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + 0.1250*p[0]*p[1]*p[2];
7806
7807
7808
7809 break;
7810 case 5:
7811 *value = -0.0625 + -0.1250*p[0]*p[0]*p[1]*p[2] + 0.1250*p[1]*p[1]*p[0]*p[2] + -0.1250*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + -0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + -0.1250*p[0]*p[1]*p[2];
7812
7813
7814 break;
7815 case 6:
7816 *value = -0.0625 + 0.1250*p[0]*p[0]*p[1]*p[2] + 0.1250*p[1]*p[1]*p[0]*p[2] + 0.1250*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + 0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + 0.1250*p[0]*p[1]*p[2];
7817
7818
7819
7820 break;
7821 case 7:
7822 *value = -0.0625 + 0.1250*p[0]*p[0]*p[1]*p[2] + -0.1250*p[1]*p[1]*p[0]*p[2] + -0.1250*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1]*p[2] + 0.1250*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[1]*p[1]*p[2]*p[2]*p[0] + 0.0625*p[0]*p[0]*p[1]*p[1] + 0.0625*p[0]*p[0]*p[2]*p[2] + 0.0625*p[1]*p[1]*p[2]*p[2] + -0.1250*p[0]*p[1]*p[2];
7823
7824
7825 break;
7826 case 8:
7827 *value = 0.1250 + 0.2500*p[1]*p[2] + -0.2500*p[1]*p[1]*p[2] + -0.2500*p[2]*p[2]*p[1] + -0.2500*p[0]*p[0]*p[1]*p[2] + 0.2500*p[0]*p[0]*p[1]*p[1]*p[2] + 0.2500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + 0.1250*p[1]*p[1]*p[2]*p[2];
7828
7829
7830
7831 break;
7832 case 9:
7833 *value = 0.1250 + -0.2500*p[2] + -0.2500*p[0]*p[2] + 0.2500*p[1]*p[1]*p[2] + 0.2500*p[2]*p[2]*p[0] + 0.2500*p[1]*p[1]*p[0]*p[2] + -0.2500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.1250*p[0]*p[0]*p[1]*p[1] + 0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7834
7835
7836
7837 break;
7838 case 10:
7839 *value = 0.1250 + -0.2500*p[1]*p[2] + -0.2500*p[1]*p[1]*p[2] + 0.2500*p[2]*p[2]*p[1] + 0.2500*p[0]*p[0]*p[1]*p[2] + 0.2500*p[0]*p[0]*p[1]*p[1]*p[2] + -0.2500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + 0.1250*p[1]*p[1]*p[2]*p[2];
7840
7841
7842
7843 break;
7844 case 11:
7845 *value = 0.1250 + -0.2500*p[2] + 0.2500*p[0]*p[2] + 0.2500*p[1]*p[1]*p[2] + -0.2500*p[2]*p[2]*p[0] + -0.2500*p[1]*p[1]*p[0]*p[2] + 0.2500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.1250*p[0]*p[0]*p[1]*p[1] + 0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7846
7847
7848
7849 break;
7850 case 12:
7851 *value = 0.1250 + -0.2500*p[1]*p[2] + 0.2500*p[1]*p[1]*p[2] + -0.2500*p[2]*p[2]*p[1] + 0.2500*p[0]*p[0]*p[1]*p[2] + -0.2500*p[0]*p[0]*p[1]*p[1]*p[2] + 0.2500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + 0.1250*p[1]*p[1]*p[2]*p[2];
7852
7853
7854
7855 break;
7856 case 13:
7857 *value = 0.1250 + 0.2500*p[2] + 0.2500*p[0]*p[2] + -0.2500*p[1]*p[1]*p[2] + 0.2500*p[2]*p[2]*p[0] + -0.2500*p[1]*p[1]*p[0]*p[2] + -0.0000*p[2]*p[2]*p[0]*p[1] + -0.2500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.1250*p[0]*p[0]*p[1]*p[1] + 0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7858
7859
7860
7861 break;
7862 case 14:
7863 *value = 0.1250 + 0.2500*p[1]*p[2] + 0.2500*p[1]*p[1]*p[2] + 0.2500*p[2]*p[2]*p[1] + -0.2500*p[0]*p[0]*p[1]*p[2] + 0.0000*p[1]*p[1]*p[0]*p[2] + -0.2500*p[0]*p[0]*p[1]*p[1]*p[2] + -0.2500*p[0]*p[0]*p[2]*p[2]*p[1] + -0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + 0.1250*p[1]*p[1]*p[2]*p[2];
7864
7865
7866
7867 break;
7868 case 15:
7869 *value = 0.1250 + 0.2500*p[2] + -0.2500*p[0]*p[2] + -0.2500*p[1]*p[1]*p[2] + -0.2500*p[2]*p[2]*p[0] + -0.0000*p[0]*p[0]*p[1]*p[2] + 0.2500*p[1]*p[1]*p[0]*p[2] + 0.2500*p[1]*p[1]*p[2]*p[2]*p[0] + -0.1250*p[0]*p[0]*p[1]*p[1] + 0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7870
7871
7872
7873 break;
7874 case 16:
7875 *value = 0.1250 + -0.2500*p[0] + -0.2500*p[1] + 0.2500*p[0]*p[1] + 0.2500*p[2]*p[2]*p[0] + 0.2500*p[2]*p[2]*p[1] + -0.2500*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7876
7877
7878
7879 break;
7880 case 17:
7881 *value = 0.1250 + 0.2500*p[0] + -0.2500*p[1] + -0.2500*p[0]*p[1] + -0.2500*p[2]*p[2]*p[0] + 0.2500*p[2]*p[2]*p[1] + 0.2500*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7882
7883
7884
7885 break;
7886 case 18:
7887 *value = 0.1250 + 0.2500*p[0] + 0.2500*p[1] + 0.2500*p[0]*p[1] + -0.2500*p[2]*p[2]*p[0] + -0.2500*p[2]*p[2]*p[1] + -0.2500*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7888
7889
7890 break;
7891 case 19:
7892 *value = 0.1250 + -0.2500*p[0] + 0.2500*p[1] + -0.2500*p[0]*p[1] + 0.2500*p[2]*p[2]*p[0] + -0.2500*p[2]*p[2]*p[1] + 0.2500*p[2]*p[2]*p[0]*p[1] + 0.1250*p[0]*p[0]*p[1]*p[1] + -0.1250*p[0]*p[0]*p[2]*p[2] + -0.1250*p[1]*p[1]*p[2]*p[2];
7893
7894
7895 break;
7896 default:
7897 break;
7898 }
7899 break;
7900 }
7901
7902 }
7903
7904 }
7905}
7906template <class SC, class LO, class GO, class NO>
7907void FE<SC,LO,GO,NO>::buildTransformation(const vec_int_Type& element,
7908 vec2D_dbl_ptr_Type pointsRep,
7909 SmallMatrix<SC>& B,
7910 std::string FEType){
7911
7912 TEUCHOS_TEST_FOR_EXCEPTION( (B.size()<2 || B.size()>3), std::logic_error, "Initialize SmallMatrix for transformation.");
7913 UN index;
7914 UN index0 = element.at(0);
7915 if (FEType[0]=='P') {
7916 for (UN j=0; j<B.size(); j++) {
7917 index = element.at(j+1);
7918 for (UN i=0; i<B.size(); i++) {
7919 B[i][j] = pointsRep->at(index).at(i) - pointsRep->at(index0).at(i);
7920 }
7921 }
7922 }
7923 else if (FEType[0]=='Q'){
7924 TEUCHOS_TEST_FOR_EXCEPTION( B.size()!=3, std::logic_error, "Transformation for quadrilateral elements only in 3D.");
7925 std::vector<int> indexVec(3);
7926 indexVec[0] = element[1]; indexVec[1] = element[3]; indexVec[2] = element[4];
7927 for (UN j=0; j<B.size(); j++) {
7928 for (UN i=0; i<B.size(); i++) {
7929 B[i][j] = ( pointsRep->at( indexVec[j] ).at(i) - pointsRep->at( index0 ).at(i) ) / 2.;
7930 }
7931 }
7932 }
7933}
7934
7935template <class SC, class LO, class GO, class NO>
7936void FE<SC,LO,GO,NO>::buildTransformation(const vec_int_Type& element,
7937 vec2D_dbl_ptr_Type pointsRep,
7938 SmallMatrix<SC>& B,
7939 vec_dbl_Type& b,
7940 std::string FEType){
7941
7942 TEUCHOS_TEST_FOR_EXCEPTION( (B.size()<2 || B.size()>3), std::logic_error, "Initialize SmallMatrix for transformation.");
7943 UN index;
7944 UN index0 = element.at(0);
7945 if (FEType[0]=='P') {
7946 for (UN j=0; j<B.size(); j++) {
7947 index = element.at(j+1);
7948 for (UN i=0; i<B.size(); i++) {
7949 B[i][j] = pointsRep->at(index).at(i) - pointsRep->at(index0).at(i);
7950 }
7951 }
7952 for (UN i=0; i<B.size(); i++)
7953 b[i] = pointsRep->at(index0).at(i);
7954 }
7955 else if (FEType[0]=='Q'){
7956 TEUCHOS_TEST_FOR_EXCEPTION( B.size()!=3, std::logic_error, "Transformation for quadrilateral elements only in 3D.");
7957 std::vector<int> indexVec(3);
7958 indexVec[0] = element[1]; indexVec[1] = element[3]; indexVec[2] = element[4];
7959 for (UN j=0; j<B.size(); j++) {
7960 for (UN i=0; i<B.size(); i++) {
7961 B[i][j] = ( pointsRep->at( indexVec[j] ).at(i) - pointsRep->at( index0 ).at(i) ) / 2.;
7962 }
7963 }
7964 for (UN i=0; i<B.size(); i++)
7965 b[i] = pointsRep->at(index0).at(i);
7966
7967 }
7968}
7969
7970template <class SC, class LO, class GO, class NO>
7971void FE<SC,LO,GO,NO>::buildTransformationSurface(const vec_int_Type& element,
7972 vec2D_dbl_ptr_Type pointsRep,
7973 SmallMatrix<SC>& B,
7974 vec_dbl_Type& b,
7975 std::string FEType){
7976 // small matrix always square
7977 TEUCHOS_TEST_FOR_EXCEPTION( (B.size()<2 || B.size()>3), std::logic_error, "Initialize SmallMatrix for transformation.");
7978 UN index;
7979 UN index0 = element.at(0);
7980 if (FEType[0]=='P') {
7981 for (UN j=0; j<B.size()-1; j++) {
7982 index = element.at(j+1);
7983 for (UN i=0; i<B.size(); i++) { // dimension
7984 B[i][j] = pointsRep->at(index).at(i) - pointsRep->at(index0).at(i);
7985 }
7986 }
7987 for (UN i=0; i<B.size(); i++)
7988 b[i] = pointsRep->at(index0).at(i);
7989 }
7990 else if (FEType[0]=='Q'){
7991 TEUCHOS_TEST_FOR_EXCEPTION( B.size()!=3, std::logic_error, "No Transformation for surface integrals.");
7992 }
7993}
7994
7995template <class SC, class LO, class GO, class NO>
7996void FE<SC,LO,GO,NO>::gradPhi(int dim,
7997 int intFE,
7998 int i,
7999 vec_dbl_Type &p,
8000 vec_dbl_ptr_Type &value){
8001 if (dim==2) {
8002 switch (intFE) {
8003 case 0://P0
8004 switch (i) {
8005 case 0:
8006 value->at(0)= 0.;
8007 value->at(1)= 0.;
8008 break;
8009 }
8010 break;
8011 case 1://P1
8012 switch (i) {
8013 case 0:
8014 value->at(0)= -1.;
8015 value->at(1)= -1.;
8016 break;
8017 case 1:
8018 value->at(0)= 1.;
8019 value->at(1)= 0.;
8020 break;
8021 case 2:
8022 value->at(0)= 0.;
8023 value->at(1)= 1.;
8024 break;
8025 }
8026 break;
8027 case 2://P2
8028 switch (i) {
8029 case 0:
8030 value->at(0)= 1. - 4.*(1 - p[0] - p[1]);
8031 value->at(1)= 1. - 4.*(1 - p[0] - p[1]);
8032 break;
8033 case 1:
8034 value->at(0)= 4.*p[0] - 1;
8035 value->at(1)= 0.;
8036 break;
8037 case 2:
8038 value->at(0)= 0.;
8039 value->at(1)= 4.*p[1] - 1;
8040 break;
8041 case 3:
8042 value->at(0)= 4 * (1. - 2*p[0] - p[1]);
8043 value->at(1)= -4 * p[0];
8044 break;
8045 case 4:
8046 value->at(0)= 4.*p[1];
8047 value->at(1)= 4.*p[0];
8048 break;
8049 case 5:
8050 value->at(0)= - 4.*p[1];
8051 value->at(1)= 4 * (1. - p[0] - 2*p[1]);
8052 break;
8053 }
8054 break;
8055 }
8056 }
8057 else if(dim==3) {
8058 switch (intFE) {
8059 case 0://P0
8060 switch (i) {
8061 case 0:
8062 value->at(0)= 0.;
8063 value->at(1)= 0.;
8064 value->at(2)= 0.;
8065 break;
8066 }
8067 break;
8068 case 1://P1
8069 switch (i) {
8070 case 0:
8071 value->at(0)= -1.;
8072 value->at(1)= -1.;
8073 value->at(2)= -1.;
8074 break;
8075 case 1:
8076 value->at(0)= 1.;
8077 value->at(1)= 0.;
8078 value->at(2)= 0.;
8079 break;
8080 case 2:
8081 value->at(0)= 0.;
8082 value->at(1)= 1.;
8083 value->at(2)= 0.;
8084 break;
8085 case 3:
8086 value->at(0)= 0.;
8087 value->at(1)= 0.;
8088 value->at(2)= 1.;
8089 break;
8090 }
8091 break;
8092 case 2://P2
8093 switch (i) {
8094 case 0:
8095 value->at(0)= -3. + 4.*p[0] + 4.*p[1] + 4.*p[2];
8096 value->at(1)= -3. + 4.*p[0] + 4.*p[1] + 4.*p[2];
8097 value->at(2)= -3. + 4.*p[0] + 4.*p[1] + 4.*p[2];
8098 break;
8099 case 1:
8100 value->at(0)= 4.*p[0] - 1;
8101 value->at(1)= 0.;
8102 value->at(2)= 0.;
8103 break;
8104 case 2:
8105 value->at(0)= 0.;
8106 value->at(1)= 4.*p[1] - 1;
8107 value->at(2)= 0.;
8108 break;
8109 case 3:
8110 value->at(0)= 0.;
8111 value->at(1)= 0.;
8112 value->at(2)= 4.*p[2] - 1;
8113 break;
8114 case 4:
8115 value->at(0)= 4. - 8.*p[0] - 4.*p[1] - 4.*p[2];
8116 value->at(1)= - 4.*p[0];
8117 value->at(2)= - 4.*p[0];
8118 break;
8119 case 5:
8120 value->at(0)= 4.*p[1];
8121 value->at(1)= 4.*p[0];
8122 value->at(2)= 0.;
8123 break;
8124 case 6:
8125 value->at(0)= - 4.*p[1];
8126 value->at(1)= 4. - 4.*p[0] - 8.*p[1] - 4.*p[2];
8127 value->at(2)= - 4.*p[1];
8128 break;
8129 case 7:
8130 value->at(0)= - 4.*p[2];
8131 value->at(1)= - 4.*p[2];
8132 value->at(2)= 4. - 4.*p[0] - 4.*p[1] - 8.*p[2];
8133 break;
8134 case 8:
8135 value->at(0)= 4.*p[2];
8136 value->at(1)= 0.;
8137 value->at(2)= 4.*p[0];
8138 break;
8139 case 9:
8140 value->at(0)= 0.;
8141 value->at(1)= 4.*p[2];
8142 value->at(2)= 4.*p[1];
8143 break;
8144 }
8145 break;
8146 case 3: //Q1
8147 {
8148 double a = 1./8;
8149 switch (i) {
8150 case 0:
8151 value->at(0) = - a * ( 1 - p[1] ) * ( 1 - p[2] );
8152 value->at(1) = - a * ( 1 - p[0] ) * ( 1 - p[2] );
8153 value->at(2) = - a * ( 1 - p[0] ) * ( 1 - p[1] );
8154 break;
8155 case 1:
8156 value->at(0) = a * ( 1 - p[1] ) * ( 1 - p[2] );
8157 value->at(1) = - a * ( 1 + p[0] ) * ( 1 - p[2] );
8158 value->at(2) = - a * ( 1 + p[0] ) * ( 1 - p[1] );
8159 break;
8160 case 2:
8161 value->at(0) = a * ( 1 + p[1] ) * ( 1 - p[2] );
8162 value->at(1) = a * ( 1 + p[0] ) * ( 1 - p[2] );
8163 value->at(2) = - a * ( 1 + p[0] ) * ( 1 + p[1] );
8164 break;
8165 case 3:
8166 value->at(0) = - a * ( 1 + p[1] ) * ( 1 - p[2] );
8167 value->at(1) = a * ( 1 - p[0] ) * ( 1 - p[2] );
8168 value->at(2) = - a * ( 1 - p[0] ) * ( 1 + p[1] );
8169 break;
8170 case 4:
8171 value->at(0) = - a * ( 1 - p[1] ) * ( 1 + p[2] );
8172 value->at(1) = - a * ( 1 - p[0] ) * ( 1 + p[2] );
8173 value->at(2) = a * ( 1 - p[0] ) * ( 1 - p[1] );
8174 break;
8175 case 5:
8176 value->at(0) = a * ( 1 - p[1] ) * ( 1 + p[2] );
8177 value->at(1) = - a * ( 1 + p[0] ) * ( 1 + p[2] );
8178 value->at(2) = a * ( 1 + p[0] ) * ( 1 - p[1] );
8179 break;
8180 case 6:
8181 value->at(0) = a * ( 1 + p[1] ) * ( 1 + p[2] );
8182 value->at(1) = a * ( 1 + p[0] ) * ( 1 + p[2] );
8183 value->at(2) = a * ( 1 + p[0] ) * ( 1 + p[1] );
8184 break;
8185 case 7:
8186 value->at(0) = - a * ( 1 + p[1] ) * ( 1 + p[2] );
8187 value->at(1) = a * ( 1 - p[0] ) * ( 1 + p[2] );
8188 value->at(2) = a * ( 1 - p[0] ) * ( 1 + p[1] );
8189 break;
8190 default:
8191 break;
8192 }
8193 break;
8194 }
8195 case 4: //Q2
8196 {
8197 switch (i) {
8198 case 0:
8199 value->at(0) = 0.125*2*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[2] + 0.125*p[2]*p[2]*p[1] + -0.125*2*p[0]*p[1]*p[1]*p[2] + -0.125*2*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2] + -0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8200 value->at(1) = 0.125*p[0]*p[0]*p[2] + 0.125*2*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0] + -0.125*p[0]*p[0]*2*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2] + -0.125*2*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8201 value->at(2) = 0.125*p[0]*p[0]*p[1] + 0.125*p[1]*p[1]*p[0] + 0.125*2*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1] + -0.125*p[0]*p[0]*2*p[2]*p[1] + -0.125*p[1]*p[1]*2*p[2]*p[0] + -0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8202 break;
8203 case 1:
8204 value->at(0) = 0.125*2*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[2] + -0.125*p[2]*p[2]*p[1] + -0.125*2*p[0]*p[1]*p[1]*p[2] + -0.125*2*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2] + 0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8205 value->at(1) = 0.125*p[0]*p[0]*p[2] + -0.125*2*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0] + -0.125*p[0]*p[0]*2*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2] + 0.125*2*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8206 value->at(2) = 0.125*p[0]*p[0]*p[1] + -0.125*p[1]*p[1]*p[0] + -0.125*2*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1] + -0.125*p[0]*p[0]*2*p[2]*p[1] + 0.125*p[1]*p[1]*2*p[2]*p[0] + 0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8207 break;
8208 case 2:
8209 value->at(0) = -0.125*2*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[2] + 0.125*p[2]*p[2]*p[1] + -0.125*2*p[0]*p[1]*p[1]*p[2] + 0.125*2*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2] + -0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8210 value->at(1) = -0.125*p[0]*p[0]*p[2] + -0.125*2*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0] + -0.125*p[0]*p[0]*2*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2] + 0.125*2*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8211 value->at(2) = -0.125*p[0]*p[0]*p[1] + -0.125*p[1]*p[1]*p[0] + 0.125*2*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1] + 0.125*p[0]*p[0]*2*p[2]*p[1] + 0.125*p[1]*p[1]*2*p[2]*p[0] + -0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8212 break;
8213 case 3:
8214 value->at(0) = -0.125*2*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[2] + -0.125*p[2]*p[2]*p[1] + -0.125*2*p[0]*p[1]*p[1]*p[2] + 0.125*2*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2] + 0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8215 value->at(1) = -0.125*p[0]*p[0]*p[2] + 0.125*2*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0] + -0.125*p[0]*p[0]*2*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2] + -0.125*2*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8216 value->at(2) = -0.125*p[0]*p[0]*p[1] + 0.125*p[1]*p[1]*p[0] + -0.125*2*p[2]*p[0]*p[1] + -0.125*p[0]*p[0]*p[1]*p[1] + 0.125*p[0]*p[0]*2*p[2]*p[1] + -0.125*p[1]*p[1]*2*p[2]*p[0] + 0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8217 break;
8218 case 4:
8219 value->at(0) = -0.125*2*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[2] + 0.125*p[2]*p[2]*p[1] + 0.125*2*p[0]*p[1]*p[1]*p[2] + -0.125*2*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2] + 0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8220 value->at(1) = -0.125*p[0]*p[0]*p[2] + -0.125*2*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0] + 0.125*p[0]*p[0]*2*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2] + -0.125*2*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8221 value->at(2) = -0.125*p[0]*p[0]*p[1] + -0.125*p[1]*p[1]*p[0] + 0.125*2*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1] + -0.125*p[0]*p[0]*2*p[2]*p[1] + -0.125*p[1]*p[1]*2*p[2]*p[0] + 0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8222 break;
8223 case 5:
8224 value->at(0) = -0.125*2*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[2] + -0.125*p[2]*p[2]*p[1] + 0.125*2*p[0]*p[1]*p[1]*p[2] + -0.125*2*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2] + -0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8225 value->at(1) = -0.125*p[0]*p[0]*p[2] + 0.125*2*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0] + 0.125*p[0]*p[0]*2*p[1]*p[2] + -0.125*p[0]*p[0]*p[2]*p[2] + 0.125*2*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8226 value->at(2) = -0.125*p[0]*p[0]*p[1] + 0.125*p[1]*p[1]*p[0] + -0.125*2*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1] + -0.125*p[0]*p[0]*2*p[2]*p[1] + 0.125*p[1]*p[1]*2*p[2]*p[0] + -0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8227 break;
8228 case 6:
8229 value->at(0) = 0.125*2*p[0]*p[1]*p[2] + 0.125*p[1]*p[1]*p[2] + 0.125*p[2]*p[2]*p[1] + 0.125*2*p[0]*p[1]*p[1]*p[2] + 0.125*2*p[0]*p[2]*p[2]*p[1] + 0.125*p[1]*p[1]*p[2]*p[2] + 0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8230 value->at(1) = 0.125*p[0]*p[0]*p[2] + 0.125*2*p[1]*p[0]*p[2] + 0.125*p[2]*p[2]*p[0] + 0.125*p[0]*p[0]*2*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2] + 0.125*2*p[1]*p[2]*p[2]*p[0] + 0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8231 value->at(2) = 0.125*p[0]*p[0]*p[1] + 0.125*p[1]*p[1]*p[0] + 0.125*2*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1] + 0.125*p[0]*p[0]*2*p[2]*p[1] + 0.125*p[1]*p[1]*2*p[2]*p[0] + 0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8232 break;
8233 case 7:
8234 value->at(0) = 0.125*2*p[0]*p[1]*p[2] + -0.125*p[1]*p[1]*p[2] + -0.125*p[2]*p[2]*p[1] + 0.125*2*p[0]*p[1]*p[1]*p[2] + 0.125*2*p[0]*p[2]*p[2]*p[1] + -0.125*p[1]*p[1]*p[2]*p[2] + -0.125*p[1]*p[2] + 0.125*2*p[0]*p[1]*p[1]*p[2]*p[2];
8235 value->at(1) = 0.125*p[0]*p[0]*p[2] + -0.125*2*p[1]*p[0]*p[2] + -0.125*p[2]*p[2]*p[0] + 0.125*p[0]*p[0]*2*p[1]*p[2] + 0.125*p[0]*p[0]*p[2]*p[2] + -0.125*2*p[1]*p[2]*p[2]*p[0] + -0.125*p[0]*p[2] + 0.125*p[0]*p[0]*2*p[1]*p[2]*p[2];
8236 value->at(2) = 0.125*p[0]*p[0]*p[1] + -0.125*p[1]*p[1]*p[0] + -0.125*2*p[2]*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1] + 0.125*p[0]*p[0]*2*p[2]*p[1] + -0.125*p[1]*p[1]*2*p[2]*p[0] + -0.125*p[0]*p[1] + 0.125*p[0]*p[0]*p[1]*p[1]*2*p[2];
8237 break;
8238 case 8:
8239 value->at(0) = -0.250*2*p[0]*p[1]*p[2] + 0.250*2*p[0]*p[1]*p[1]*p[2] + 0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8240 value->at(1) = 0.250*p[2] + -0.250*2*p[1]*p[2] + -0.250*p[2]*p[2] + -0.250*p[0]*p[0]*p[2] + 0.250*p[0]*p[0]*2*p[1]*p[2] + 0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8241 value->at(2) = 0.250*p[1] + -0.250*p[1]*p[1] + -0.250*2*p[2]*p[1] + -0.250*p[0]*p[0]*p[1] + 0.250*p[0]*p[0]*p[1]*p[1] + 0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8242 break;
8243 case 9:
8244 value->at(0) = -0.250*p[2] + -0.250*2*p[0]*p[2] + 0.250*p[2]*p[2] + 0.250*p[1]*p[1]*p[2] + 0.250*2*p[0]*p[1]*p[1]*p[2] + -0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[2]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8245 value->at(1) = -0.250*p[0]*p[0]*p[2] + 0.250*2*p[1]*p[0]*p[2] + 0.250*p[0]*p[0]*2*p[1]*p[2] + -0.250*2*p[1]*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8246 value->at(2) = -0.250*p[0] + -0.250*p[0]*p[0] + 0.250*2*p[2]*p[0] + 0.250*p[1]*p[1]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[1]*p[1]*2*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8247 break;
8248 case 10:
8249 value->at(0) = 0.250*2*p[0]*p[1]*p[2] + 0.250*2*p[0]*p[1]*p[1]*p[2] + -0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8250 value->at(1) = -0.250*p[2] + -0.250*2*p[1]*p[2] + 0.250*p[2]*p[2] + 0.250*p[0]*p[0]*p[2] + 0.250*p[0]*p[0]*2*p[1]*p[2] + -0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8251 value->at(2) = -0.250*p[1] + -0.250*p[1]*p[1] + 0.250*2*p[2]*p[1] + 0.250*p[0]*p[0]*p[1] + 0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8252 break;
8253 case 11:
8254 value->at(0) = 0.250*p[2] + -0.250*2*p[0]*p[2] + -0.250*p[2]*p[2] + -0.250*p[1]*p[1]*p[2] + 0.250*2*p[0]*p[1]*p[1]*p[2] + 0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[2]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8255 value->at(1) = -0.250*p[0]*p[0]*p[2] + -0.250*2*p[1]*p[0]*p[2] + 0.250*p[0]*p[0]*2*p[1]*p[2] + 0.250*2*p[1]*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8256 value->at(2) = 0.250*p[0] + -0.250*p[0]*p[0] + -0.250*2*p[2]*p[0] + -0.250*p[1]*p[1]*p[0] + 0.250*p[0]*p[0]*p[1]*p[1] + 0.250*p[1]*p[1]*2*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8257 break;
8258 case 12:
8259 value->at(0) = 0.250*2*p[0]*p[1]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2] + 0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8260 value->at(1) = -0.250*p[2] + 0.250*2*p[1]*p[2] + -0.250*p[2]*p[2] + 0.250*p[0]*p[0]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2] + 0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8261 value->at(2) = -0.250*p[1] + 0.250*p[1]*p[1] + -0.250*2*p[2]*p[1] + 0.250*p[0]*p[0]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1] + 0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8262 break;
8263 case 13:
8264 value->at(0) = 0.250*p[2] + 0.250*2*p[0]*p[2] + 0.250*p[2]*p[2] + -0.250*p[1]*p[1]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2] + -0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[2]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8265 value->at(1) = 0.250*p[0]*p[0]*p[2] + -0.250*2*p[1]*p[0]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2] + -0.250*2*p[1]*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8266 value->at(2) = 0.250*p[0] + 0.250*p[0]*p[0] + 0.250*2*p[2]*p[0] + -0.250*p[1]*p[1]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[1]*p[1]*2*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8267 break;
8268 case 14:
8269 value->at(0) = -0.250*2*p[0]*p[1]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2] + -0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8270 value->at(1) = 0.250*p[2] + 0.250*2*p[1]*p[2] + 0.250*p[2]*p[2] + -0.250*p[0]*p[0]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2] + -0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8271 value->at(2) = 0.250*p[1] + 0.250*p[1]*p[1] + 0.250*2*p[2]*p[1] + -0.250*p[0]*p[0]*p[1] + -0.250*p[0]*p[0]*p[1]*p[1] + -0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8272 break;
8273 case 15:
8274 value->at(0) = -0.250*p[2] + 0.250*2*p[0]*p[2] + -0.250*p[2]*p[2] + 0.250*p[1]*p[1]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2] + 0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[2]*p[2] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8275 value->at(1) = 0.250*p[0]*p[0]*p[2] + 0.250*2*p[1]*p[0]*p[2] + -0.250*p[0]*p[0]*2*p[1]*p[2] + 0.250*2*p[1]*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8276 value->at(2) = -0.250*p[0] + 0.250*p[0]*p[0] + -0.250*2*p[2]*p[0] + 0.250*p[1]*p[1]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1] + 0.250*p[1]*p[1]*2*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[2] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8277 break;
8278 case 16:
8279 value->at(0) = 0.250*p[1] + -0.250*2*p[0]*p[1] + -0.250*p[1]*p[1] + -0.250*p[2]*p[2]*p[1] + 0.250*2*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[1]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8280 value->at(1) = 0.250*p[0] + -0.250*p[0]*p[0] + -0.250*2*p[1]*p[0] + -0.250*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[1] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8281 value->at(2) = -0.250*2*p[2]*p[0]*p[1] + 0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8282 break;
8283 case 17:
8284 value->at(0) = -0.250*p[1] + -0.250*2*p[0]*p[1] + 0.250*p[1]*p[1] + 0.250*p[2]*p[2]*p[1] + 0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[1]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8285 value->at(1) = -0.250*p[0] + -0.250*p[0]*p[0] + 0.250*2*p[1]*p[0] + 0.250*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*p[2]*p[2] + -0.250*2*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[1] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8286 value->at(2) = 0.250*2*p[2]*p[0]*p[1] + 0.250*p[0]*p[0]*2*p[2]*p[1] + -0.250*p[1]*p[1]*2*p[2]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8287 break;
8288 case 18:
8289 value->at(0) = 0.250*p[1] + 0.250*2*p[0]*p[1] + 0.250*p[1]*p[1] + -0.250*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[2]*p[2]*p[1] + -0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[1]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8290 value->at(1) = 0.250*p[0] + 0.250*p[0]*p[0] + 0.250*2*p[1]*p[0] + -0.250*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*p[2]*p[2] + -0.250*2*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[1] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8291 value->at(2) = -0.250*2*p[2]*p[0]*p[1] + -0.250*p[0]*p[0]*2*p[2]*p[1] + -0.250*p[1]*p[1]*2*p[2]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8292 break;
8293 case 19:
8294 value->at(0) = -0.250*p[1] + 0.250*2*p[0]*p[1] + -0.250*p[1]*p[1] + 0.250*p[2]*p[2]*p[1] + -0.250*2*p[0]*p[2]*p[2]*p[1] + 0.250*p[1]*p[1]*p[2]*p[2] + 0.250*2*p[0]*p[1]*p[1] + -0.250*2*p[0]*p[1]*p[1]*p[2]*p[2];
8295 value->at(1) = -0.250*p[0] + 0.250*p[0]*p[0] + -0.250*2*p[1]*p[0] + 0.250*p[2]*p[2]*p[0] + -0.250*p[0]*p[0]*p[2]*p[2] + 0.250*2*p[1]*p[2]*p[2]*p[0] + 0.250*p[0]*p[0]*2*p[1] + -0.250*p[0]*p[0]*2*p[1]*p[2]*p[2];
8296 value->at(2) = 0.250*2*p[2]*p[0]*p[1] + -0.250*p[0]*p[0]*2*p[2]*p[1] + 0.250*p[1]*p[1]*2*p[2]*p[0] + -0.250*p[0]*p[0]*p[1]*p[1]*2*p[2];
8297 break;
8298 case 20:
8299 value->at(0) = 0.500*2*p[0]*p[1] + -0.500*2*p[0]*p[2]*p[2]*p[1] + -0.500*2*p[0]*p[1]*p[1] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8300 value->at(1) = -0.500 + 0.500*2*p[1] + 0.500*p[0]*p[0] + 0.500*p[2]*p[2] + -0.500*p[0]*p[0]*p[2]*p[2] + -0.500*p[0]*p[0]*2*p[1] + -0.500*2*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8301 value->at(2) = 0.500*2*p[2]*p[1] + -0.500*p[0]*p[0]*2*p[2]*p[1] + -0.500*p[1]*p[1]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8302 break;
8303 case 21:
8304 value->at(0) = 0.500 + 0.500*2*p[0] + -0.500*p[1]*p[1] + -0.500*p[2]*p[2] + 0.500*p[1]*p[1]*p[2]*p[2] + -0.500*2*p[0]*p[1]*p[1] + -0.500*2*p[0]*p[2]*p[2] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8305 value->at(1) = -0.500*2*p[1]*p[0] + 0.500*2*p[1]*p[2]*p[2]*p[0] + -0.500*p[0]*p[0]*2*p[1] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8306 value->at(2) = -0.500*2*p[2]*p[0] + 0.500*p[1]*p[1]*2*p[2]*p[0] + -0.500*p[0]*p[0]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8307 break;
8308 case 22:
8309 value->at(0) = -0.500*2*p[0]*p[1] + 0.500*2*p[0]*p[2]*p[2]*p[1] + -0.500*2*p[0]*p[1]*p[1] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8310 value->at(1) = 0.500 + 0.500*2*p[1] + -0.500*p[0]*p[0] + -0.500*p[2]*p[2] + 0.500*p[0]*p[0]*p[2]*p[2] + -0.500*p[0]*p[0]*2*p[1] + -0.500*2*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8311 value->at(2) = -0.500*2*p[2]*p[1] + 0.500*p[0]*p[0]*2*p[2]*p[1] + -0.500*p[1]*p[1]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8312 break;
8313 case 23:
8314 value->at(0) = -0.500 + 0.500*2*p[0] + 0.500*p[1]*p[1] + 0.500*p[2]*p[2] + -0.500*p[1]*p[1]*p[2]*p[2] + -0.500*2*p[0]*p[1]*p[1] + -0.500*2*p[0]*p[2]*p[2] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8315 value->at(1) = 0.500*2*p[1]*p[0] + -0.500*2*p[1]*p[2]*p[2]*p[0] + -0.500*p[0]*p[0]*2*p[1] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8316 value->at(2) = 0.500*2*p[2]*p[0] + -0.500*p[1]*p[1]*2*p[2]*p[0] + -0.500*p[0]*p[0]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8317 break;
8318 case 24:
8319 value->at(0) = 0.500*2*p[0]*p[2] + -0.500*2*p[0]*p[1]*p[1]*p[2] + -0.500*2*p[0]*p[2]*p[2] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8320 value->at(1) = 0.500*p[0]*p[0]*p[2] + 0.500*2*p[1]*p[2] + -0.500*p[0]*p[0]*2*p[1]*p[2] + -0.500*2*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8321 value->at(2) = -0.500 + 0.500*2*p[2] + 0.500*p[0]*p[0] + 0.500*p[1]*p[1] + -0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[0]*p[0]*2*p[2] + -0.500*p[1]*p[1]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8322 break;
8323 case 25:
8324 value->at(0) = -1.000*2*p[0] + 1.000*2*p[0]*p[1]*p[1] + 1.000*2*p[0]*p[2]*p[2] + -1.000*2*p[0]*p[1]*p[1]*p[2]*p[2];
8325 value->at(1) = -1.000*2*p[1] + 1.000*p[0]*p[0]*2*p[1] + 1.000*2*p[1]*p[2]*p[2] + -1.000*p[0]*p[0]*2*p[1]*p[2]*p[2];
8326 value->at(2) = -1.000*2*p[2] + 1.000*p[0]*p[0]*2*p[2] + 1.000*p[1]*p[1]*2*p[2] + -1.000*p[0]*p[0]*p[1]*p[1]*2*p[2];
8327 break;
8328 case 26:
8329 value->at(0) = -0.500*2*p[0]*p[2] + 0.500*2*p[0]*p[1]*p[1]*p[2] + -0.500*2*p[0]*p[2]*p[2] + 0.500*2*p[0]*p[1]*p[1]*p[2]*p[2];
8330 value->at(1) = -0.500*p[0]*p[0]*p[2] + -0.500*2*p[1]*p[2] + 0.500*p[0]*p[0]*2*p[1]*p[2] + -0.500*2*p[1]*p[2]*p[2] + 0.500*p[0]*p[0]*2*p[1]*p[2]*p[2];
8331 value->at(2) = 0.500 + 0.500*2*p[2] + -0.500*p[0]*p[0] + -0.500*p[1]*p[1] + 0.500*p[0]*p[0]*p[1]*p[1] + -0.500*p[0]*p[0]*2*p[2] + -0.500*p[1]*p[1]*2*p[2] + 0.500*p[0]*p[0]*p[1]*p[1]*2*p[2];
8332 break;
8333 default:
8334 break;
8335 }
8336 break;
8337 }
8338 case 5: //Q2-20
8339 {
8340 std::cout << "Warning! Q2-20 not working correct!" << std::endl;
8341 double a = 1./8;
8342 double b = 1./4;
8343 switch (i) {
8344 case 0:
8345 (*value)[0] = a * (p[1] - 1) * (p[2] - 1) * (2 * p[0] + p[1] + p[2] + 1);
8346 (*value)[1] = a * (p[0] - 1) * (p[2] - 1) * (p[0] + 2 * p[1] + p[2] + 1);
8347 (*value)[2] = a * (p[0] - 1) * (p[1] - 1) * (p[0] + p[1] + 2 * p[2] + 1);
8348 break;
8349 case 1:
8350 (*value)[0] = - a * ( p[1] - 1 ) * ( p[2] - 1 ) * ( -2*p[0] + p[1] + p[2] + 1);
8351 (*value)[1] = a * ( p[0] + 1 ) * ( p[2] - 1 ) * ( p[0] - 2*p[1] - p[2] - 1);
8352 (*value)[2] = a * ( p[0] + 1 ) * ( p[1] - 1 ) * ( p[0] - p[1] - 2*p[2] - 1);
8353 break;
8354 case 2:
8355 (*value)[0] = a * ( p[1] + 1 ) * ( p[2] - 1 ) * ( -2*p[0] + p[1] - p[2] - 1);
8356 (*value)[1] = - a * ( p[0] - 1 ) * ( p[2] - 1 ) * ( p[0] - 2*p[1] + p[2] + 1);
8357 (*value)[2] = - a * ( p[0] + 1 ) * ( p[1] + 1 ) * ( p[0] + p[1] - 2*p[2] - 1);
8358 break;
8359 case 3:
8360 (*value)[0] = a * (1 + p[1]) * (-1 - 2 * p[0] + p[1] - p[2]) * (-1 + p[2]);
8361 (*value)[1] = - a * ((-1 + p[0]) * (-1 + p[2]) * (1 + p[0] - 2 * p[1] + p[2]));
8362 (*value)[2] = - a * ((-1 + p[0]) * (1 + p[1]) * (1 + p[0] - p[1] + 2 * p[2]));
8363 break;
8364 case 4:
8365 (*value)[0] = -a*(p[1] - 1) * (p[2] + 1) * (2 * p[0] + p[1] - p[2] + 1);
8366 (*value)[1] = -a*(p[0] - 1) * (p[2] + 1) * (p[0] + 2 * p[1] - p[2] + 1);
8367 (*value)[2] = -a*(p[0] - 1) * (p[1] - 1) * (p[0] + p[1] - 2 * p[2] + 1);
8368 break;
8369 case 5:
8370 (*value)[0] = a*(p[1] - 1) * (p[2] + 1) * (-2 * p[0] + p[1] - p[2] + 1);
8371 (*value)[1] = -a*(p[0] + 1) * (p[2] + 1) * (p[0] - 2 * p[1] + p[2] - 1);
8372 (*value)[2] = -a*(p[0] + 1) * (p[1] - 1) * (p[0] - p[1] + 2 * p[2] - 1);
8373 break;
8374 case 6:
8375 (*value)[0] = a*(p[1] + 1) * (p[2] + 1) * (2 * p[0] + p[1] + p[2] - 1);
8376 (*value)[1] = a*(p[0] + 1) * (p[2] + 1) * (p[0] + 2 * p[1] + p[2] - 1);
8377 (*value)[2] = a*(p[0] + 1) * (p[1] + 1) * (p[0] + p[1] + 2 * p[2] - 1);
8378 break;
8379 case 7:
8380 (*value)[0] = -a*(p[1] + 1) * (p[2] + 1) * (-2 * p[0] + p[1] + p[2] - 1);
8381 (*value)[1] = a*(p[0] - 1) * (p[2] + 1) * (p[0] - 2 * p[1] - p[2] + 1);
8382 (*value)[2] = a*(p[0] - 1) * (p[1] + 1) * (p[0] - p[1] - 2 * p[2] + 1);
8383 break;
8384 case 8:
8385 (*value)[0] = -2 * b * p[0] * (p[1] - 1) * (p[2] - 1);
8386 (*value)[1] = -b * (p[0]*p[0] - 1) * (p[2] - 1);
8387 (*value)[2] = -b * (p[0]*p[0] - 1) * (p[1] - 1);
8388 break;
8389 case 9:
8390 (*value)[0] = b * (p[1]*p[1] - 1) * (p[2] - 1);
8391 (*value)[1] = 2 * b * (p[0] + 1) * p[1] * (p[2] - 1);
8392 (*value)[2] = b * (p[0] + 1) * (p[1]*p[1] - 1);
8393 break;
8394 case 10:
8395 (*value)[0] = 2 * b * p[0] * (p[1] + 1) * (p[2] - 1);
8396 (*value)[1] = b * (p[0]*p[0] - 1) * (p[2] - 1);
8397 (*value)[2] = b * (p[0]*p[0] - 1) * (p[1] + 1);
8398 break;
8399 case 11:
8400 (*value)[0] = -b * (p[1]*p[1] - 1) * (p[2] - 1);
8401 (*value)[1] = -2 * b * (p[0] - 1) * p[1] * (p[2] - 1);
8402 (*value)[2] = -b * (p[0] - 1) * (p[1]*p[1] - 1);
8403 break;
8404 case 12:
8405 (*value)[0] = 2* b * p[0] * (p[1] - 1) * (p[2] + 1);
8406 (*value)[1] = b * (p[0]*p[0] - 1) * (p[2] + 1);
8407 (*value)[2] = b * (p[0]*p[0] - 1) * (p[1] - 1);
8408 break;
8409 case 13:
8410 (*value)[0] = -b * (p[1]*p[1] - 1) * (p[2] + 1);
8411 (*value)[1] = -2 * b * (p[0] + 1) * p[1] * (p[2] + 1);
8412 (*value)[2] = -b * (p[0] + 1) * (p[1]*p[1] - 1);
8413 break;
8414 case 14:
8415 (*value)[0] = -2 * b * p[0] * (p[1] + 1) * (p[2] + 1);
8416 (*value)[1] = -b * (p[0]*p[0] - 1) * (p[2] + 1);
8417 (*value)[2] = -b *(p[0]*p[0] - 1) * (p[1] + 1);
8418 break;
8419 case 15:
8420 (*value)[0] = b * (p[1]*p[1] - 1) * (p[2] + 1);
8421 (*value)[1] = 2 * b * (p[0] - 1) * p[1] * (p[2] + 1);
8422 (*value)[2] = b * (p[0] - 1) * (p[1]*p[1] - 1);
8423 break;
8424 case 16:
8425 (*value)[0] = -b * (p[1] - 1) * (p[2]*p[2] - 1);
8426 (*value)[1] = -b * (p[0] - 1) * (p[2]*p[2] - 1);
8427 (*value)[2] = -2 * b * (p[0] - 1) * (p[1] - 1) * p[2];
8428 break;
8429 case 17:
8430 (*value)[0] = b * (p[1] - 1) * (p[2]*p[2] - 1);
8431 (*value)[1] = b * (p[0] + 1) * (p[2]*p[2] - 1);
8432 (*value)[2] = 2 * b * (p[0] + 1) * (p[1] - 1) * p[2];
8433 break;
8434 case 18:
8435 (*value)[0] = -b * (p[1] + 1) * (p[2]*p[2] - 1);
8436 (*value)[1] = -b * (p[0] + 1) * (p[2]*p[2] - 1);
8437 (*value)[0] = -2 * b * (p[0] + 1) * (p[1] + 1) * p[2];
8438 break;
8439 case 19:
8440 (*value)[0] = b * (p[1] + 1) * (p[2]*p[2] - 1);
8441 (*value)[1] = b * (p[0] - 1) * (p[2]*p[2] - 1);
8442 (*value)[2] = 2 * b * (p[0] - 1) * (p[1] + 1) * p[2];
8443 break;
8444 default:
8445 break;
8446 }
8447 break;
8448 }
8449 }
8450 }
8451}
8452
8453template <class SC, class LO, class GO, class NO>
8454void FE<SC,LO,GO,NO>::getQuadratureValues(int dim,
8455 int Degree,
8456 vec2D_dbl_ptr_Type &QuadPts,
8457 vec_dbl_ptr_Type &QuadW,
8458 std::string FEType){
8459 double a, b, c, P1, P2;
8460
8461 double b1,b2,c1,c2,d,e,f,g,h,i,j;
8462 if (dim==1){
8463 // points are for interval [0,1]
8464 TEUCHOS_TEST_FOR_EXCEPTION(Degree>2, std::runtime_error, "Quadrature rule in 1d only up to degree 3.");
8465 switch (Degree) {
8466 case 0:
8467 QuadPts.reset(new vec2D_dbl_Type(1,vec_dbl_Type(1,0.0)));
8468 QuadW->resize(1);
8469 QuadPts->at(0).at(0) = 0.5;
8470 QuadW->at(0) = 1.;
8471 break;
8472 case 1:
8473 QuadPts.reset(new vec2D_dbl_Type(1,vec_dbl_Type(1,0.0)));
8474 QuadW->resize(1);
8475 QuadPts->at(0).at(0) = 0.5;
8476 QuadW->at(0) = 1.;
8477 break;
8478 case 2:
8479 QuadPts.reset(new vec2D_dbl_Type(2,vec_dbl_Type(1,0.0)));
8480 QuadW->resize(2);
8481 QuadPts->at(0).at(0) = - 0.5/std::sqrt(3.)+0.5;
8482 QuadPts->at(1).at(0) = 0.5/std::sqrt(3.)+0.5;
8483 QuadW->at(0) = .5;
8484 QuadW->at(1) = .5;
8485 break;
8486 case 3:
8487 QuadPts.reset(new vec2D_dbl_Type(2,vec_dbl_Type(1,0.0)));
8488 QuadW->resize(2);
8489 QuadPts->at(0).at(0) = - 0.5/std::sqrt(3.)+0.5;
8490 QuadPts->at(1).at(0) = 0.5/std::sqrt(3.)+0.5;
8491 QuadW->at(0) = .5;
8492 QuadW->at(1) = .5;
8493 break;
8494 default:
8495 break;
8496 }
8497 }
8498 if (dim==2) {
8499
8500 TEUCHOS_TEST_FOR_EXCEPTION(Degree>7, std::runtime_error, "Quadrature rule in 2d only up to degree 7.");
8501 if (Degree==3 || Degree==4)
8502 Degree=5;
8503
8504 if (Degree==6)
8505 Degree=7;
8506 switch (Degree) {
8507 case 1:
8508
8509 QuadPts.reset(new vec2D_dbl_Type(1,vec_dbl_Type(2,0.0)));
8510 QuadW->resize(1);
8511 QuadPts->at(0).at(0) = 1/3.;
8512 QuadPts->at(0).at(1) = 1/3.;
8513 QuadW->at(0) = 1/2.;
8514 break;
8515
8516 case 2:
8517
8518 QuadPts.reset(new vec2D_dbl_Type(3,vec_dbl_Type(2,0.0)));
8519 QuadW->resize(3);
8520 a = 1/6.;
8521 QuadPts->at(0).at(0) = 0.5;
8522 QuadPts->at(0).at(1) = 0.5;
8523
8524 QuadPts->at(1).at(0) = 0.;
8525 QuadPts->at(1).at(1) = 0.5;
8526
8527 QuadPts->at(2).at(0) = 0.5;
8528 QuadPts->at(2).at(1) = 0.;
8529
8530 QuadW->at(0) = a;
8531 QuadW->at(1) = a;
8532 QuadW->at(2) = a;
8533
8534 break;
8535
8536 case 5:
8537 QuadPts.reset(new vec2D_dbl_Type(7,vec_dbl_Type(2,0.0)));
8538 QuadW->resize(7);
8539 a = 0.470142064105115;
8540 b = 0.101286507323456;
8541 P1 = 0.066197076394253;
8542 P2 = 0.062969590272413;
8543
8544 QuadPts->at(0).at(0) = 1/3.;
8545 QuadPts->at(0).at(1) = 1/3.;
8546
8547 QuadPts->at(1).at(0) = a;
8548 QuadPts->at(1).at(1) = a;
8549
8550 QuadPts->at(2).at(0) = 1-2.*a;
8551 QuadPts->at(2).at(1) = a;
8552
8553 QuadPts->at(3).at(0) = a;
8554 QuadPts->at(3).at(1) = 1-2.*a;
8555
8556 QuadPts->at(4).at(0) = b;
8557 QuadPts->at(4).at(1) = b;
8558
8559 QuadPts->at(5).at(0) = 1-2.*b;
8560 QuadPts->at(5).at(1) = b;
8561
8562 QuadPts->at(6).at(0) = b;
8563 QuadPts->at(6).at(1) = 1-2.*b;
8564
8565 QuadW->at(0) = 9/80.;
8566 QuadW->at(1) = P1;
8567 QuadW->at(2) = P1;
8568 QuadW->at(3) = P1;
8569 QuadW->at(4) = P2;
8570 QuadW->at(5) = P2;
8571 QuadW->at(6) = P2;
8572
8573 break;
8574 case 7:
8575 // 28 Punkte
8576
8577 QuadPts.reset(new vec2D_dbl_Type(28,vec_dbl_Type(2,0.0)));
8578 QuadW.reset(new vec_dbl_Type(28,0.0));
8579
8580 // x punkt
8581 QuadPts->at(0).at(0) = 0.777777777777778;
8582 QuadPts->at(1).at(0) = 0.111111111111111;
8583 QuadPts->at(2).at(0) = 0.111111111111111;
8584 QuadPts->at(3).at(0) = 0.666666666666667;
8585 QuadPts->at(4).at(0) = 0.222222222222222;
8586 QuadPts->at(5).at(0) = 0.111111111111111;
8587 QuadPts->at(6).at(0) = 0.222222222222222;
8588 QuadPts->at(7).at(0) = 0.111111111111111;
8589 QuadPts->at(8).at(0) = 0.666666666666667;
8590 QuadPts->at(9).at(0) = 0.555555555555556;
8591 QuadPts->at(10).at(0) = 0.333333333333333;
8592 QuadPts->at(11).at(0) = 0.111111111111111;
8593 QuadPts->at(12).at(0) = 0.333333333333333;
8594 QuadPts->at(13).at(0) = 0.111111111111111;
8595 QuadPts->at(14).at(0) = 0.555555555555556;
8596 QuadPts->at(15).at(0) = 0.555555555555556;
8597 QuadPts->at(16).at(0) = 0.222222222222222;
8598 QuadPts->at(17).at(0) = 0.222222222222222;
8599 QuadPts->at(18).at(0) = 0.444444444444444;
8600 QuadPts->at(19).at(0) = 0.444444444444444;
8601 QuadPts->at(20).at(0) = 0.111111111111111;
8602 QuadPts->at(21).at(0) = 0.444444444444444;
8603 QuadPts->at(22).at(0) = 0.333333333333333;
8604 QuadPts->at(23).at(0) = 0.222222222222222;
8605 QuadPts->at(24).at(0) = 0.333333333333333;
8606 QuadPts->at(25).at(0) = 0.222222222222222;
8607 QuadPts->at(26).at(0) = 0.444444444444444;
8608 QuadPts->at(27).at(0) = 0.333333333333333;
8609
8610 // y punkt
8611 QuadPts->at(0).at(1) = 0.111111111111111;
8612 QuadPts->at(1).at(1) = 0.111111111111111;
8613 QuadPts->at(2).at(1) = 0.777777777777778;
8614 QuadPts->at(3).at(1) = 0.222222222222222;
8615 QuadPts->at(4).at(1) = 0.111111111111111;
8616 QuadPts->at(5).at(1) = 0.666666666666667;
8617 QuadPts->at(6).at(1) = 0.666666666666667;
8618 QuadPts->at(7).at(1) = 0.222222222222222;
8619 QuadPts->at(8).at(1) = 0.111111111111111;
8620 QuadPts->at(9).at(1) = 0.333333333333333;
8621 QuadPts->at(10).at(1) = 0.111111111111111;
8622 QuadPts->at(11).at(1) = 0.555555555555556;
8623 QuadPts->at(12).at(1) = 0.555555555555556;
8624 QuadPts->at(13).at(1) = 0.333333333333333;
8625 QuadPts->at(14).at(1) = 0.111111111111111;
8626 QuadPts->at(15).at(1) = 0.222222222222222;
8627 QuadPts->at(16).at(1) = 0.222222222222222;
8628 QuadPts->at(17).at(1) = 0.555555555555556;
8629 QuadPts->at(18).at(1) = 0.444444444444444;
8630 QuadPts->at(19).at(1) = 0.111111111111111;
8631 QuadPts->at(20).at(1) = 0.444444444444444;
8632 QuadPts->at(21).at(1) = 0.333333333333333;
8633 QuadPts->at(22).at(1) = 0.222222222222222;
8634 QuadPts->at(23).at(1) = 0.444444444444444;
8635 QuadPts->at(24).at(1) = 0.444444444444444;
8636 QuadPts->at(25).at(1) = 0.333333333333333;
8637 QuadPts->at(26).at(1) = 0.222222222222222;
8638 QuadPts->at(27).at(1) = 0.333333333333333;
8639
8640 // Gewichte
8641 QuadW->at(0) = 0.342410714285714/2.0;
8642 QuadW->at(1) = 0.342410714285714/2.0;
8643 QuadW->at(2) = 0.342410714285714/2.0;
8644 QuadW->at(3) = -0.561160714285714/2.0;
8645 QuadW->at(4) = -0.561160714285714/2.0;
8646 QuadW->at(5) = -0.561160714285714/2.0;
8647 QuadW->at(6) = -0.561160714285714/2.0;
8648 QuadW->at(7) = -0.561160714285714/2.0;
8649 QuadW->at(8) = -0.561160714285714/2.0;
8650 QuadW->at(9) = 1.295089285714286/2.0;
8651 QuadW->at(10) = 1.295089285714286/2.0;
8652 QuadW->at(11) = 1.295089285714286/2.0;
8653 QuadW->at(12) = 1.295089285714286/2.0;
8654 QuadW->at(13) = 1.295089285714286/2.0;
8655 QuadW->at(14) = 1.295089285714286/2.0;
8656 QuadW->at(15) = 0.172767857142857/2.0;
8657 QuadW->at(16) = 0.172767857142857/2.0;
8658 QuadW->at(17) = 0.172767857142857/2.0;
8659 QuadW->at(18) = -1.354910714285714/2.0;
8660 QuadW->at(19) = -1.354910714285714/2.0;
8661 QuadW->at(20) = -1.354910714285714/2.0;
8662 QuadW->at(21) = -0.408482142857143/2.0;
8663 QuadW->at(22) = -0.408482142857143/2.0;
8664 QuadW->at(23) = -0.408482142857143/2.0;
8665 QuadW->at(24) = -0.408482142857143/2.0;
8666 QuadW->at(25) = -0.408482142857143/2.0;
8667 QuadW->at(26) = -0.408482142857143/2.0;
8668 QuadW->at(27) = 1.566517857142857/2.0;
8669
8670 break;
8671
8672 }
8673 }
8674 else if(dim==3){
8675 if (FEType.at(0)=='P') {
8676 if (Degree==2)
8677 Degree=3;
8678 if (Degree==4)
8679 Degree=5;
8680
8681 TEUCHOS_TEST_FOR_EXCEPTION(Degree>6, std::runtime_error, "Tetrahedron quadrature rules only up to degree 6 available.");
8682
8683 switch (Degree) {
8684 case 1:
8685 QuadPts.reset(new vec2D_dbl_Type(1,vec_dbl_Type(3,0.0)));
8686 QuadW->resize(1);
8687 QuadPts->at(0).at(0) = 0.25;
8688 QuadPts->at(0).at(1) = 0.25;
8689 QuadPts->at(0).at(2) = 0.25;
8690 QuadW->at(0) = 1/6.;
8691 break;
8692
8693 case 3:
8694 QuadPts.reset(new vec2D_dbl_Type(5,vec_dbl_Type(3,0.0)));
8695 QuadW->resize(5);
8696 a = .25;
8697 b = 1./6.;
8698 c = .5;
8699 QuadPts->at(0).at(0) = a;
8700 QuadPts->at(0).at(1) = a;
8701 QuadPts->at(0).at(2) = a;
8702
8703 QuadPts->at(1).at(0) = b;
8704 QuadPts->at(1).at(1) = b;
8705 QuadPts->at(1).at(2) = b;
8706
8707 QuadPts->at(2).at(0) = b;
8708 QuadPts->at(2).at(1) = b;
8709 QuadPts->at(2).at(2) = c;
8710
8711 QuadPts->at(3).at(0) = b;
8712 QuadPts->at(3).at(1) = c;
8713 QuadPts->at(3).at(2) = b;
8714
8715 QuadPts->at(4).at(0) = c;
8716 QuadPts->at(4).at(1) = b;
8717 QuadPts->at(4).at(2) = b;
8718
8719 QuadW->at(0) = -2./15.;
8720 QuadW->at(1) = 3./40.;
8721 QuadW->at(2) = 3./40.;
8722 QuadW->at(3) = 3./40.;
8723 QuadW->at(4) = 3./40.;
8724 break;
8725 case 4:
8726 QuadPts.reset(new vec2D_dbl_Type(11,vec_dbl_Type(3,0.0)));
8727 QuadW->resize(11);
8728
8729 a = .785714285714286;
8730 b = .071428571428571;
8731 c = .100596423833201;
8732 d = .399403576166799;
8733
8734 QuadPts->at(0).at(0) = .25;
8735 QuadPts->at(0).at(1) = .25;
8736 QuadPts->at(0).at(2) = .25;
8737
8738 QuadPts->at(1).at(0) = a;
8739 QuadPts->at(1).at(1) = b;
8740 QuadPts->at(1).at(2) = b;
8741
8742 QuadPts->at(2).at(0) = b;
8743 QuadPts->at(2).at(1) = b;
8744 QuadPts->at(2).at(2) = b;
8745
8746 QuadPts->at(3).at(0) = b;
8747 QuadPts->at(3).at(1) = b;
8748 QuadPts->at(3).at(2) = a;
8749
8750 QuadPts->at(4).at(0) = b;
8751 QuadPts->at(4).at(1) = a;
8752 QuadPts->at(4).at(2) = b;
8753
8754 QuadPts->at(5).at(0) = c;
8755 QuadPts->at(5).at(1) = d;
8756 QuadPts->at(5).at(2) = d;
8757
8758 QuadPts->at(6).at(0) = d;
8759 QuadPts->at(6).at(1) = c;
8760 QuadPts->at(6).at(2) = d;
8761
8762 QuadPts->at(7).at(0) = d;
8763 QuadPts->at(7).at(1) = d;
8764 QuadPts->at(7).at(2) = c;
8765
8766 QuadPts->at(8).at(0) = d;
8767 QuadPts->at(8).at(1) = c;
8768 QuadPts->at(8).at(2) = c;
8769
8770 QuadPts->at(9).at(0) = c;
8771 QuadPts->at(9).at(1) = d;
8772 QuadPts->at(9).at(2) = c;
8773
8774 QuadPts->at(10).at(0) = c;
8775 QuadPts->at(10).at(1) = c;
8776 QuadPts->at(10).at(2) = d;
8777
8778 a = -.078933333333333;
8779 b = .045733333333333;
8780 c= .149333333333333;
8781
8782
8783 QuadW->at(0) = a;
8784
8785 QuadW->at(1) = b;
8786 QuadW->at(2) = b;
8787 QuadW->at(3) = b;
8788 QuadW->at(4) = b;
8789
8790 QuadW->at(5) = c;
8791 QuadW->at(6) = c;
8792 QuadW->at(7) = c;
8793 QuadW->at(8) = c;
8794 QuadW->at(9) = c;
8795 QuadW->at(10) = c;
8796
8797 case 5:
8798 QuadPts.reset(new vec2D_dbl_Type(15,vec_dbl_Type(3,0.0)));
8799 QuadW->resize(15);
8800 a = 0.25;
8801 b1 = (7.+std::sqrt(15.))/34.;
8802 b2 = (7.-std::sqrt(15.))/34.;
8803 c1 = (13.-3.*std::sqrt(15.))/34.;
8804 c2 = (13.+3.*std::sqrt(15.))/34.;
8805 d = (5.-std::sqrt(15.))/20.;
8806 e = (5.+std::sqrt(15.))/20.;
8807
8808 QuadPts->at(0).at(0) = a;
8809 QuadPts->at(0).at(1) = a;
8810 QuadPts->at(0).at(2) = a;
8811
8812 QuadPts->at(1).at(0) = b1;
8813 QuadPts->at(1).at(1) = b1;
8814 QuadPts->at(1).at(2) = b1;
8815
8816 QuadPts->at(2).at(0) = b1;
8817 QuadPts->at(2).at(1) = b1;
8818 QuadPts->at(2).at(2) = c1;
8819
8820 QuadPts->at(3).at(0) = b1;
8821 QuadPts->at(3).at(1) = c1;
8822 QuadPts->at(3).at(2) = b1;
8823
8824 QuadPts->at(4).at(0) = c1;
8825 QuadPts->at(4).at(1) = b1;
8826 QuadPts->at(4).at(2) = b1;
8827
8828 QuadPts->at(5).at(0) = b2;
8829 QuadPts->at(5).at(1) = b2;
8830 QuadPts->at(5).at(2) = b2;
8831
8832 QuadPts->at(6).at(0) = b2;
8833 QuadPts->at(6).at(1) = b2;
8834 QuadPts->at(6).at(2) = c2;
8835
8836 QuadPts->at(7).at(0) = b2;
8837 QuadPts->at(7).at(1) = c2;
8838 QuadPts->at(7).at(2) = b2;
8839
8840 QuadPts->at(8).at(0) = c2;
8841 QuadPts->at(8).at(1) = b2;
8842 QuadPts->at(8).at(2) = b2;
8843
8844 QuadPts->at(9).at(0) = d;
8845 QuadPts->at(9).at(1) = d;
8846 QuadPts->at(9).at(2) = e;
8847
8848 QuadPts->at(10).at(0) = d;
8849 QuadPts->at(10).at(1) = e;
8850 QuadPts->at(10).at(2) = d;
8851
8852 QuadPts->at(11).at(0) = e;
8853 QuadPts->at(11).at(1) = d;
8854 QuadPts->at(11).at(2) = d;
8855
8856 QuadPts->at(12).at(0) = d;
8857 QuadPts->at(12).at(1) = e;
8858 QuadPts->at(12).at(2) = e;
8859
8860 QuadPts->at(13).at(0) = e;
8861 QuadPts->at(13).at(1) = d;
8862 QuadPts->at(13).at(2) = e;
8863
8864 QuadPts->at(14).at(0) = e;
8865 QuadPts->at(14).at(1) = e;
8866 QuadPts->at(14).at(2) = d;
8867
8868
8869 P1 = (2665.-14.*std::sqrt(15.))/226800.;
8870 P2 = (2665.+14.*std::sqrt(15.))/226800.;
8871 b = 5./567.;
8872
8873 QuadW->at(0) = 8./405.;
8874 QuadW->at(1) = P1;
8875 QuadW->at(2) = P1;
8876 QuadW->at(3) = P1;
8877 QuadW->at(4) = P1;
8878
8879 QuadW->at(5) = P2;
8880 QuadW->at(6) = P2;
8881 QuadW->at(7) = P2;
8882 QuadW->at(8) = P2;
8883
8884 QuadW->at(9) = b;
8885 QuadW->at(10) = b;
8886 QuadW->at(11) = b;
8887 QuadW->at(12) = b;
8888 QuadW->at(13) = b;
8889 QuadW->at(14) = b;
8890
8891 break;
8892 case 6: //Keast
8893 QuadPts.reset(new vec2D_dbl_Type(24,vec_dbl_Type(3,0.0)));
8894 QuadW->resize(24);
8895 a = .356191386222545;
8896 b = .214602871259152;
8897 c = .877978124396166;
8898 d = .040673958534611;
8899 f = .032986329573173;
8900 g = .322337890142276;
8901 h = .269672331458316;
8902 i = .063661001875018;
8903 j = .603005664791649;
8904
8905 QuadPts->at(0).at(0) = a;
8906 QuadPts->at(0).at(1) = b;
8907 QuadPts->at(0).at(2) = b;
8908
8909 QuadPts->at(1).at(0) = b;
8910 QuadPts->at(1).at(1) = b;
8911 QuadPts->at(1).at(2) = b;
8912
8913 QuadPts->at(2).at(0) = b;
8914 QuadPts->at(2).at(1) = b;
8915 QuadPts->at(2).at(2) = a;
8916
8917 QuadPts->at(3).at(0) = b;
8918 QuadPts->at(3).at(1) = a;
8919 QuadPts->at(3).at(2) = b;
8920
8921 QuadPts->at(4).at(0) = c;
8922 QuadPts->at(4).at(1) = d;
8923 QuadPts->at(4).at(2) = d;
8924
8925 QuadPts->at(5).at(0) = d;
8926 QuadPts->at(5).at(1) = d;
8927 QuadPts->at(5).at(2) = d;
8928
8929 QuadPts->at(6).at(0) = d;
8930 QuadPts->at(6).at(1) = d;
8931 QuadPts->at(6).at(2) = c;
8932
8933 QuadPts->at(7).at(0) = d;
8934 QuadPts->at(7).at(1) = c;
8935 QuadPts->at(7).at(2) = d;
8936
8937 QuadPts->at(8).at(0) = f;
8938 QuadPts->at(8).at(1) = g;
8939 QuadPts->at(8).at(2) = g;
8940
8941 QuadPts->at(9).at(0) = g;
8942 QuadPts->at(9).at(1) = g;
8943 QuadPts->at(9).at(2) = g;
8944
8945 QuadPts->at(10).at(0) = g;
8946 QuadPts->at(10).at(1) = g;
8947 QuadPts->at(10).at(2) = f;
8948
8949 QuadPts->at(11).at(0) = g;
8950 QuadPts->at(11).at(1) = f;
8951 QuadPts->at(11).at(2) = g;
8952
8953 QuadPts->at(12).at(0) = h;
8954 QuadPts->at(12).at(1) = i;
8955 QuadPts->at(12).at(2) = i;
8956
8957 QuadPts->at(13).at(0) = i;
8958 QuadPts->at(13).at(1) = h;
8959 QuadPts->at(13).at(2) = i;
8960
8961 QuadPts->at(14).at(0) = i;
8962 QuadPts->at(14).at(1) = i;
8963 QuadPts->at(14).at(2) = h;
8964
8965 QuadPts->at(15).at(0) = j;
8966 QuadPts->at(15).at(1) = i;
8967 QuadPts->at(15).at(2) = i;
8968
8969 QuadPts->at(16).at(0) = i;
8970 QuadPts->at(16).at(1) = j;
8971 QuadPts->at(16).at(2) = i;
8972
8973 QuadPts->at(17).at(0) = i;
8974 QuadPts->at(17).at(1) = i;
8975 QuadPts->at(17).at(2) = j;
8976
8977 QuadPts->at(18).at(0) = i;
8978 QuadPts->at(18).at(1) = h;
8979 QuadPts->at(18).at(2) = j;
8980
8981 QuadPts->at(19).at(0) = h;
8982 QuadPts->at(19).at(1) = j;
8983 QuadPts->at(19).at(2) = i;
8984
8985 QuadPts->at(20).at(0) = j;
8986 QuadPts->at(20).at(1) = i;
8987 QuadPts->at(20).at(2) = h;
8988
8989 QuadPts->at(21).at(0) = i;
8990 QuadPts->at(21).at(1) = j;
8991 QuadPts->at(21).at(2) = h;
8992
8993 QuadPts->at(22).at(0) = h;
8994 QuadPts->at(22).at(1) = i;
8995 QuadPts->at(22).at(2) = j;
8996
8997 QuadPts->at(23).at(0) = j;
8998 QuadPts->at(23).at(1) = h;
8999 QuadPts->at(23).at(2) = j;
9000
9001 a = .039922750258168;
9002 b = .010077211055321;
9003 c = .055357181543654;
9004 d = .048214285714286;
9005
9006 QuadW->at(0) = a;
9007 QuadW->at(1) = a;
9008 QuadW->at(2) = a;
9009 QuadW->at(3) = a;
9010 QuadW->at(4) = b;
9011 QuadW->at(5) = b;
9012 QuadW->at(6) = b;
9013 QuadW->at(7) = b;
9014 QuadW->at(8) = c;
9015 QuadW->at(9) = c;
9016 QuadW->at(10) = c;
9017 QuadW->at(11) = c;
9018 QuadW->at(12) = d;
9019 QuadW->at(13) = d;
9020 QuadW->at(14) = d;
9021 QuadW->at(15) = d;
9022 QuadW->at(16) = d;
9023 QuadW->at(17) = d;
9024 QuadW->at(18) = d;
9025 QuadW->at(19) = d;
9026 QuadW->at(20) = d;
9027 QuadW->at(21) = d;
9028 QuadW->at(22) = d;
9029 QuadW->at(23) = d;
9030 }
9031 }
9032 else if(FEType.at(0)=='Q'){
9033 if (Degree<=3)
9034 Degree=3;
9035 else if(Degree==4 || Degree==5)
9036 Degree=5;
9037 else if(Degree==6|| Degree==7)
9038 Degree=7;
9039
9040 TEUCHOS_TEST_FOR_EXCEPTION(Degree>7, std::logic_error, "Quadrature rules for degree > 7 not available.");
9041
9042 switch (Degree) {
9043 case 1: // 1 points in each direction; order 1
9044 {
9045 QuadPts.reset(new vec2D_dbl_Type(1,vec_dbl_Type(3,0.0)));
9046 QuadW->resize(1);
9047 QuadW->at(0) = 2.;
9048 break;
9049 }
9050 case 3: // 2 points in each direction; order 3
9051 {
9052 double d = 1./std::sqrt(3);
9053 QuadPts.reset(new vec2D_dbl_Type(8,vec_dbl_Type(3,0.0)));
9054 QuadW->resize(8);
9055 QuadPts->at(0).at(0) = -d;
9056 QuadPts->at(0).at(1) = -d;
9057 QuadPts->at(0).at(2) = -d;
9058 QuadW->at(0) = 1.;
9059
9060 QuadPts->at(1).at(0) = -d;
9061 QuadPts->at(1).at(1) = -d;
9062 QuadPts->at(1).at(2) = d;
9063 QuadW->at(1) = 1.;
9064
9065 QuadPts->at(2).at(0) = -d;
9066 QuadPts->at(2).at(1) = d;
9067 QuadPts->at(2).at(2) = -d;
9068 QuadW->at(2) = 1.;
9069
9070 QuadPts->at(3).at(0) = -d;
9071 QuadPts->at(3).at(1) = d;
9072 QuadPts->at(3).at(2) = d;
9073 QuadW->at(3) = 1.;
9074
9075 QuadPts->at(4).at(0) = d;
9076 QuadPts->at(4).at(1) = -d;
9077 QuadPts->at(4).at(2) = -d;
9078 QuadW->at(4) = 1.;
9079
9080 QuadPts->at(5).at(0) = d;
9081 QuadPts->at(5).at(1) = -d;
9082 QuadPts->at(5).at(2) = d;
9083 QuadW->at(5) = 1.;
9084
9085 QuadPts->at(6).at(0) = d;
9086 QuadPts->at(6).at(1) = d;
9087 QuadPts->at(6).at(2) = -d;
9088 QuadW->at(6) = 1.;
9089
9090 QuadPts->at(7).at(0) = d;
9091 QuadPts->at(7).at(1) = d;
9092 QuadPts->at(7).at(2) = d;
9093 QuadW->at(7) = 1.;
9094 break;
9095 }
9096 case 5: // 3 points in each direction; order 5
9097 {
9098 double a=std::sqrt(3./5);
9099 double b=5./9;
9100 double c=8./9;
9101 std::vector<double> p(3);
9102 p[0] = -a; p[1] = 0.; p[2] = a;
9103 std::vector<double> w(3);
9104 w[0] = b; w[1] = c; w[2] = b;
9105 QuadPts.reset(new vec2D_dbl_Type(27,vec_dbl_Type(3,0.0)));
9106 QuadW->resize(27);
9107 int counter=0;
9108 for (int i=0; i<3; i++) {
9109 for (int j=0; j<3; j++) {
9110 for (int k=0; k<3; k++) {
9111 QuadPts->at(counter)[0] = p[k];
9112 QuadPts->at(counter)[1] = p[j];
9113 QuadPts->at(counter)[2] = p[i];
9114 QuadW->at(counter) = w[k]*w[j]*w[i];
9115 counter++;
9116 }
9117 }
9118 }
9119 break;
9120 }
9121 case 7: // 4 points in each direction; order 7
9122 {
9123 double aa = 2./7 * std::sqrt(6./5) ;
9124 std::vector<double> p(4);
9125 p[0] = - std::sqrt(3./7 + aa);
9126 p[1] = - std::sqrt(3./7 - aa);
9127 p[2] = -p[1];
9128 p[3] = -p[0];
9129
9130 double bb = std::sqrt(30.);
9131 std::vector<double> w(4);
9132 w[0] = ( 18. - bb ) / 36;
9133 w[1] = ( 18. + bb ) / 36;
9134 w[2] = w[1];
9135 w[3] = w[0];
9136
9137 QuadPts.reset(new vec2D_dbl_Type(64,vec_dbl_Type(3,0.0)));
9138 QuadW->resize(64);
9139
9140 int counter=0;
9141 for (int i=0; i<4; i++) {
9142 for (int j=0; j<4; j++) {
9143 for (int k=0; k<4; k++) {
9144 QuadPts->at(counter)[0] = p[k];
9145 QuadPts->at(counter)[1] = p[j];
9146 QuadPts->at(counter)[2] = p[i];
9147 QuadW->at(counter) = w[k]*w[j]*w[i];
9148 counter++;
9149 }
9150 }
9151 }
9152 break;
9153 }
9154 }
9155 }
9156 }
9157
9158}
9159
9160template <class SC, class LO, class GO, class NO>
9161int FE<SC,LO,GO,NO>::getPhi(vec2D_dbl_ptr_Type &Phi,
9162 vec_dbl_ptr_Type &weightsPhi,
9163 int dim,
9164 std::string FEType,
9165 int Degree,
9166 std::string FETypeQuadPoints){
9167
9168 int nmbLocElPts;
9169 int intFE;
9170 double value;
9171 vec2D_dbl_ptr_Type QuadPts;
9172 if (dim==1) {
9173 this->getQuadratureValues(dim, Degree, QuadPts, weightsPhi, FEType);
9174 if (FEType == "P0") {
9175 nmbLocElPts = 1;
9176 intFE = 0;
9177 }
9178 else if (FEType == "P1") {
9179 nmbLocElPts = 2;
9180 intFE = 1;
9181 }
9182 else if (FEType == "P2") {
9183 nmbLocElPts = 3;
9184 intFE = 2;
9185 }
9186 Phi.reset( new vec2D_dbl_Type( weightsPhi->size(), vec_dbl_Type( nmbLocElPts, 0.0 ) ) );
9187 for (int k=0; k<Phi->size(); k++ ){
9188 for (int i=0; i<Phi->at(0).size(); i++) {
9189 this->phi(dim,intFE,i,QuadPts->at(k),&value);
9190 Phi->at(k).at(i) = value;
9191 }
9192 }
9193
9194 }
9195 else if (dim==2) {
9196 this->getQuadratureValues(dim, Degree, QuadPts, weightsPhi, FEType);
9197 if (FEType == "P0") {
9198 nmbLocElPts = 1;
9199 intFE = 0;
9200 }
9201 else if (FEType == "P1") {
9202 nmbLocElPts = 3;
9203 intFE = 1;
9204 }
9205 else if (FEType == "P2") {
9206 nmbLocElPts = 6;
9207 intFE = 2;
9208 }
9209
9210 Phi.reset(new vec2D_dbl_Type(weightsPhi->size(),vec_dbl_Type(nmbLocElPts,0.0)));
9211
9212 for (int k=0; k<Phi->size(); k++ ){
9213 for (int i=0; i<Phi->at(0).size(); i++) {
9214 this->phi(dim,intFE,i,QuadPts->at(k),&value);
9215 Phi->at(k).at(i) = value;
9216 }
9217 }
9218 }
9219 else if(dim==3){
9220 if (FETypeQuadPoints!="")
9221 this->getQuadratureValues(dim, Degree, QuadPts, weightsPhi, FETypeQuadPoints);
9222 else
9223 this->getQuadratureValues(dim, Degree, QuadPts, weightsPhi, FEType);
9224
9225 if (FEType == "P0") {
9226 nmbLocElPts = 1;
9227 intFE = 0;
9228 }
9229 else if (FEType == "P1") {
9230 nmbLocElPts = 4;
9231 intFE = 1;
9232 }
9233 else if (FEType == "P2") {
9234 nmbLocElPts = 10;
9235 intFE = 2;
9236 }
9237 else if (FEType == "Q1") {
9238 nmbLocElPts = 8;
9239 intFE = 3;
9240 }
9241 else if (FEType == "Q2") {
9242 nmbLocElPts = 27;
9243 intFE = 4;
9244 }
9245 else if (FEType == "Q2-20") {
9246 nmbLocElPts = 20;
9247 intFE = 5;
9248 }
9249 else if (FEType == "P1-disc") {
9250 nmbLocElPts = 4;
9251 intFE = 1;
9252 }
9253 else if (FEType == "P1-disc-global")
9254 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "P1-disc-global not implemented yet.");
9255
9256
9257 Phi.reset(new vec2D_dbl_Type(weightsPhi->size(),vec_dbl_Type(nmbLocElPts,0.0)));
9258
9259 for (int k=0; k<Phi->size(); k++ ){
9260 for (int i=0; i<Phi->at(0).size(); i++) {
9261 this->phi(dim,intFE,i,QuadPts->at(k),&value);
9262 Phi->at(k).at(i) = value;
9263 }
9264 }
9265 }
9266 return intFE;
9267}
9268template <class SC, class LO, class GO, class NO>
9269int FE<SC,LO,GO,NO>::getPhiGlobal(vec2D_dbl_ptr_Type &Phi,
9270 vec_dbl_ptr_Type &weightsPhi,
9271 int dim,
9272 std::string FEType,
9273 int Degree){
9274 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "getPhiGlobal not implemented yet.");
9275}
9276template <class SC, class LO, class GO, class NO>
9277int FE<SC,LO,GO,NO>::getDPhi(vec3D_dbl_ptr_Type &DPhi,
9278 vec_dbl_ptr_Type &weightsDPhi,
9279 int dim,
9280 std::string FEType,
9281 int Degree){
9282
9283 int nmbLocElPts;
9284 int intFE;
9285 vec_dbl_ptr_Type value(new vec_dbl_Type(dim,0.0));
9286 vec2D_dbl_ptr_Type QuadPts;
9287
9288 if (dim==2) {
9289 this->getQuadratureValues(dim, Degree, QuadPts, weightsDPhi, FEType);
9290 if (FEType == "P0") {
9291 nmbLocElPts = 1;
9292 intFE = 0;
9293 }
9294 else if (FEType == "P1") {
9295 nmbLocElPts = 3;
9296 intFE = 1;
9297 }
9298 else if (FEType == "P2") {
9299 nmbLocElPts = 6;
9300 intFE = 2;
9301 }
9302
9303 DPhi.reset(new vec3D_dbl_Type(weightsDPhi->size(),vec2D_dbl_Type(nmbLocElPts,vec_dbl_Type(2,0.0))));
9304
9305 for (int k=0; k<DPhi->size(); k++ ){
9306 for (int i=0; i<DPhi->at(0).size(); i++) {
9307 this->gradPhi(dim,intFE,i,QuadPts->at(k),value);
9308 for (int j=0; j<2; j++) {
9309 DPhi->at(k).at(i).at(j) = value->at(j);
9310 }
9311 }
9312 }
9313 }
9314
9315 else if(dim==3){
9316 this->getQuadratureValues(dim, Degree, QuadPts, weightsDPhi, FEType);
9317 if (FEType == "P0") {
9318 nmbLocElPts = 1;
9319 intFE = 0;
9320 }
9321 else if (FEType == "P1") {
9322 nmbLocElPts = 4;
9323 intFE = 1;
9324 }
9325 else if (FEType == "P2") {
9326 nmbLocElPts = 10;
9327 intFE = 2;
9328 }
9329 else if (FEType == "Q1") {
9330 nmbLocElPts = 8;
9331 intFE = 3;
9332 }
9333 else if (FEType == "Q2") {
9334 nmbLocElPts = 27;
9335 intFE = 4;
9336 }
9337 else if (FEType == "Q2-20") {
9338 nmbLocElPts = 20;
9339 intFE = 5;
9340 }
9341 else if (FEType == "P1-disc") {
9342 nmbLocElPts = 4;
9343 intFE = 6;
9344 }
9345 else if (FEType == "P1-disc-global")
9346 TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error ,"grad of P1-disc-global not implemented yet.");
9347
9348 DPhi.reset( new vec3D_dbl_Type( weightsDPhi->size(), vec2D_dbl_Type( nmbLocElPts, vec_dbl_Type(3,0.0) ) ) );
9349 for (int k=0; k<DPhi->size(); k++ ){
9350 for (int i=0; i<DPhi->at(0).size(); i++) {
9351 this->gradPhi(dim,intFE,i,QuadPts->at(k),value);
9352 for (int j=0; j<3; j++) {
9353 DPhi->at(k).at(i).at(j) = value->at(j);
9354 }
9355 }
9356 }
9357 }
9358
9359 return intFE;
9360}
9361*/
9362template <class SC, class LO, class GO, class NO>
9363int FE<SC,LO,GO,NO>::checkFE(int dim,
9364 std::string FEType){
9365
9366 int FEloc;
9367 std::vector<int> matches;
9368 for (int i = 0; i < domainVec_.size(); i++) {
9369 if (domainVec_.at(i)->getDimension() == dim)
9370 matches.push_back(i);
9371 }
9372
9373 bool found = false;
9374 for (int i = 0; i < matches.size();i++) {
9375 if (domainVec_.at( matches.at(i) )->getFEType() == FEType) {
9376 FEloc = matches.at(i);
9377 found = true;
9378 }
9379 }
9380
9381 TEUCHOS_TEST_FOR_EXCEPTION(!found, std::logic_error ,"Combination of dimenson(2/3) and FE Type(P1/P2) not defined yet. Use addFE(domain)");
9382
9383 return FEloc;
9384}
9385
9386
9387/*************************************************************
9388 * AceGen 6.921 MacOSX (29 Jan 19) *
9389 * Co. J. Korelc 2013 12 Feb 19 12:07:04 *
9390 **************************************************************
9391 User : Full professional version
9392 Notebook : nh3d_C
9393 Evaluation time : 6 s Mode : Optimal
9394 Number of formulae : 181 Method: Automatic
9395 Subroutine : nh3d size: 4928
9396 Total size of Mathematica code : 4928 subexpressions
9397 Total size of C code : 10178 bytes */
9398/******************* S U B R O U T I N E *********************/
9399template <class SC, class LO, class GO, class NO>
9400void FE<SC,LO,GO,NO>::nh3d(double* v, double (*E), double (*Nu), double** F , double** Pmat, double**** Amat)
9401{
9402 v[356]=2e0*F[0][2];
9403 v[354]=2e0*F[0][1];
9404 v[323]=(*E)/(1e0+(*Nu));
9405 v[3]=((*Nu)*v[323])/(1e0-2e0*(*Nu));
9406 v[5]=v[323]/2e0;
9407 v[36]=v[5]/2e0;
9408 v[65]=2e0*F[0][1];
9409 v[86]=2e0*F[0][2];
9410 v[57]=2e0*F[1][0];
9411 v[66]=2e0*F[1][1];
9412 v[87]=2e0*F[1][2];
9413 v[58]=2e0*F[2][0];
9414 v[67]=2e0*F[2][1];
9415 v[18]=F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1];
9416 v[335]=(v[18]*v[18]);
9417 v[88]=2e0*F[2][2];
9418 v[24]=F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2];
9419 v[334]=(v[24]*v[24]);
9420 v[325]=v[18]*v[24];
9421 v[22]=F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2];
9422 v[15]=Power(F[0][0],2)+Power(F[1][0],2)+Power(F[2][0],2);
9423 v[228]=-(F[2][1]*v[18]);
9424 v[225]=F[2][2]*v[18];
9425 v[217]=-(F[1][1]*v[18]);
9426 v[214]=F[1][2]*v[18];
9427 v[194]=-(F[2][0]*v[18]);
9428 v[185]=-(F[1][0]*v[18]);
9429 v[268]=F[2][1]*v[22];
9430 v[264]=-(F[2][2]*v[22]);
9431 v[255]=F[1][1]*v[22];
9432 v[251]=-(F[1][2]*v[22]);
9433 v[190]=-(F[2][0]*v[22]);
9434 v[181]=-(F[1][0]*v[22]);
9435 v[172]=-(F[0][0]*v[22]);
9436 v[20]=Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2);
9437 v[324]=-(v[20]*v[22]);
9438 v[327]=2e0*(v[324]+v[325]);
9439 v[94]=v[20]*v[88];
9440 v[92]=v[20]*v[87];
9441 v[90]=v[20]*v[86];
9442 v[138]=v[15]*v[20]-v[335];
9443 v[270]=F[2][0]*v[24];
9444 v[260]=-(F[2][2]*v[24]);
9445 v[257]=F[1][0]*v[24];
9446 v[247]=-(F[1][2]*v[24]);
9447 v[244]=F[0][0]*v[24];
9448 v[232]=-(F[0][2]*v[24]);
9449 v[222]=-(F[2][1]*v[24]);
9450 v[211]=-(F[1][1]*v[24]);
9451 v[198]=-(F[0][1]*v[24]);
9452 v[168]=v[18]*v[22]-v[15]*v[24];
9453 v[331]=2e0*v[168];
9454 v[329]=2e0*v[168];
9455 v[326]=2e0*v[168];
9456 v[38]=-(v[22]*v[22]);
9457 v[26]=Power(F[0][2],2)+Power(F[1][2],2)+Power(F[2][2],2);
9458 v[333]=v[20]*v[26]-v[334];
9459 v[351]=2e0*F[0][0]*v[333];
9460 v[236]=v[22]*v[24]-v[18]*v[26];
9461 v[332]=2e0*v[236];
9462 v[330]=2e0*v[236];
9463 v[328]=2e0*v[236];
9464 v[99]=v[26]*v[58];
9465 v[97]=v[26]*v[57];
9466 v[93]=v[26]*v[67];
9467 v[91]=v[26]*v[66];
9468 v[89]=v[26]*v[65];
9469 v[148]=v[15]*v[26]+v[38];
9470 v[29]=v[148]*v[20]+2e0*v[22]*v[325]-v[15]*v[334]-v[26]*v[335];
9471 v[336]=1e0/Power(v[29],2);
9472 v[32]=-v[5]+v[3]*std::log(std::sqrt(v[29]));
9473 v[337]=(v[3]/4e0-v[32]/2e0)*v[336];
9474 v[137]=v[337]*(F[2][1]*v[326]+F[2][0]*v[327]-v[335]*v[88]+v[15]*v[94]);
9475 v[147]=v[137]*v[138];
9476 v[136]=v[337]*(F[2][2]*v[329]+F[2][0]*v[330]+v[38]*v[67]+v[15]*v[93]);
9477 v[156]=v[136]*v[148];
9478 v[135]=v[337]*(F[2][2]*v[327]+F[2][1]*v[328]-v[334]*v[58]+v[20]*v[99]);
9479 v[165]=v[135]*v[333];
9480 v[134]=v[337]*(F[1][1]*v[326]+F[1][0]*v[327]-v[335]*v[87]+v[15]*v[92]);
9481 v[144]=v[134]*v[138];
9482 v[133]=v[337]*(F[1][2]*v[331]+F[1][0]*v[332]+v[38]*v[66]+v[15]*v[91]);
9483 v[153]=v[133]*v[148];
9484 v[132]=v[337]*(F[1][2]*v[327]+F[1][1]*v[328]-v[334]*v[57]+v[20]*v[97]);
9485 v[162]=v[132]*v[333];
9486 v[131]=v[337]*(F[0][0]*v[327]+F[0][1]*v[329]-v[335]*v[86]+v[15]*v[90]);
9487 v[130]=v[337]*(F[0][2]*v[331]+F[0][0]*v[332]+v[38]*v[65]+v[15]*v[89]);
9488 v[128]=v[337]*(F[0][2]*v[327]+F[0][1]*v[330]+v[351]);
9489 v[37]=v[32]/(2e0*v[29]);
9490 v[355]=v[37]*(2e0*v[172]+v[15]*v[86]);
9491 v[353]=v[37]*(2e0*v[232]+v[89]);
9492 v[352]=v[37]*(2e0*v[198]+v[90]);
9493 v[349]=-2e0*(F[1][0]*v[20]+v[217])*v[37];
9494 v[348]=-(v[37]*(2e0*v[185]+v[15]*v[66]));
9495 v[347]=-2e0*(F[2][0]*v[20]+v[228])*v[37];
9496 v[346]=-(v[37]*(2e0*v[194]+v[15]*v[67]));
9497 v[345]=-(v[37]*(2e0*v[251]+v[97]));
9498 v[344]=-(v[37]*(2e0*v[181]+v[15]*v[87]));
9499 v[343]=-(v[37]*(2e0*v[264]+v[99]));
9500 v[342]=-(v[37]*(2e0*v[190]+v[15]*v[88]));
9501 v[341]=-(v[37]*(2e0*v[247]+v[91]));
9502 v[340]=-(v[37]*(2e0*v[211]+v[92]));
9503 v[339]=-(v[37]*(2e0*v[260]+v[93]));
9504 v[338]=-(v[37]*(2e0*v[222]+v[94]));
9505 v[272]=v[137]*v[328]+v[37]*(2e0*v[268]+2e0*v[270]-2e0*v[18]*v[88]);
9506 v[267]=v[136]*v[328]+v[343];
9507 v[263]=v[135]*v[328]+v[339];
9508 v[259]=v[134]*v[328]+v[37]*(2e0*v[255]+2e0*v[257]-2e0*v[18]*v[87]);
9509 v[254]=v[133]*v[328]+v[345];
9510 v[250]=v[132]*v[328]+v[341];
9511 v[246]=v[131]*v[328]+v[37]*(2e0*F[0][1]*v[22]+2e0*v[244]-2e0*v[18]*v[86]);
9512 v[241]=v[130]*v[328]+2e0*(F[0][2]*v[22]-F[0][0]*v[26])*v[37];
9513 v[231]=v[137]*v[327]+v[347];
9514 v[227]=v[136]*v[327]+v[37]*(2e0*v[225]+2e0*v[270]-2e0*v[22]*v[67]);
9515 v[224]=v[135]*v[327]+v[338];
9516 v[301]=2e0*F[1][0]*v[165]+F[1][2]*v[224]+F[1][1]*v[263];
9517 v[279]=2e0*F[0][0]*v[165]+F[0][2]*v[224]+F[0][1]*v[263];
9518 v[220]=v[134]*v[327]+v[349];
9519 v[216]=v[133]*v[327]+v[37]*(2e0*v[214]+2e0*v[257]-2e0*v[22]*v[66]);
9520 v[213]=v[132]*v[327]+v[340];
9521 v[276]=2e0*F[0][0]*v[162]+F[0][2]*v[213]+F[0][1]*v[250];
9522 v[209]=v[131]*v[327]+2e0*(F[0][1]*v[18]-F[0][0]*v[20])*v[37];
9523 v[196]=v[137]*v[326]+v[346];
9524 v[314]=2e0*F[1][2]*v[147]+F[1][1]*v[196]+F[1][0]*v[231];
9525 v[296]=2e0*F[0][2]*v[147]+F[0][1]*v[196]+F[0][0]*v[231];
9526 v[192]=v[136]*v[326]+v[342];
9527 v[308]=2e0*F[1][1]*v[156]+F[1][2]*v[192]+F[1][0]*v[267];
9528 v[288]=2e0*F[0][1]*v[156]+F[0][2]*v[192]+F[0][0]*v[267];
9529 v[188]=v[135]*v[326]+v[37]*(2e0*v[225]+2e0*v[268]-2e0*v[24]*v[58]);
9530 v[187]=v[134]*v[326]+v[348];
9531 v[293]=2e0*F[0][2]*v[144]+F[0][1]*v[187]+F[0][0]*v[220];
9532 v[183]=v[133]*v[326]+v[344];
9533 v[285]=2e0*F[0][1]*v[153]+F[0][2]*v[183]+F[0][0]*v[254];
9534 v[179]=v[132]*v[326]+v[37]*(2e0*v[214]+2e0*v[255]-2e0*v[24]*v[57]);
9535 v[178]=v[131]*v[326]+2e0*(-(F[0][1]*v[15])+F[0][0]*v[18])*v[37];
9536 v[167]=v[137]*v[333]-v[338];
9537 v[303]=2e0*F[1][0]*v[167]+F[1][2]*v[231]+F[1][1]*v[272];
9538 v[281]=2e0*F[0][0]*v[167]+F[0][2]*v[231]+F[0][1]*v[272];
9539 v[166]=v[136]*v[333]-v[339];
9540 v[302]=2e0*F[1][0]*v[166]+F[1][2]*v[227]+F[1][1]*v[267];
9541 v[280]=2e0*F[0][0]*v[166]+F[0][2]*v[227]+F[0][1]*v[267];
9542 v[164]=v[134]*v[333]-v[340];
9543 v[278]=2e0*F[0][0]*v[164]+F[0][2]*v[220]+F[0][1]*v[259];
9544 v[163]=v[133]*v[333]-v[341];
9545 v[277]=2e0*F[0][0]*v[163]+F[0][2]*v[216]+F[0][1]*v[254];
9546 v[157]=v[137]*v[148]-v[342];
9547 v[309]=2e0*F[1][1]*v[157]+F[1][2]*v[196]+F[1][0]*v[272];
9548 v[289]=2e0*F[0][1]*v[157]+F[0][2]*v[196]+F[0][0]*v[272];
9549 v[155]=v[135]*v[148]-v[343];
9550 v[307]=2e0*F[1][1]*v[155]+F[1][2]*v[188]+F[1][0]*v[263];
9551 v[287]=2e0*F[0][1]*v[155]+F[0][2]*v[188]+F[0][0]*v[263];
9552 v[154]=v[134]*v[148]-v[344];
9553 v[286]=2e0*F[0][1]*v[154]+F[0][2]*v[187]+F[0][0]*v[259];
9554 v[284]=F[0][2]*v[179]+F[0][0]*v[250]+2e0*F[0][1]*(v[132]*v[148]-v[345]);
9555 v[146]=v[136]*v[138]-v[346];
9556 v[313]=2e0*F[1][2]*v[146]+F[1][1]*v[192]+F[1][0]*v[227];
9557 v[295]=2e0*F[0][2]*v[146]+F[0][1]*v[192]+F[0][0]*v[227];
9558 v[145]=v[135]*v[138]-v[347];
9559 v[312]=2e0*F[1][2]*v[145]+F[1][1]*v[188]+F[1][0]*v[224];
9560 v[294]=2e0*F[0][2]*v[145]+F[0][1]*v[188]+F[0][0]*v[224];
9561 v[292]=F[0][1]*v[183]+F[0][0]*v[216]+2e0*F[0][2]*(v[133]*v[138]-v[348]);
9562 v[291]=F[0][1]*v[179]+F[0][0]*v[213]+(v[132]*v[138]-v[349])*v[356];
9563 v[35]=v[36]+v[138]*v[37];
9564 v[310]=2e0*v[35];
9565 v[40]=v[36]+v[148]*v[37];
9566 v[304]=2e0*v[40];
9567 v[43]=v[36]+v[333]*v[37];
9568 v[297]=2e0*v[43];
9569 v[44]=v[326]*v[37];
9570 v[319]=2e0*F[2][1]*v[157]+F[2][2]*v[196]+F[2][0]*v[272]+v[44];
9571 v[306]=2e0*F[1][1]*v[154]+F[1][2]*v[187]+F[1][0]*v[259]+v[44];
9572 v[283]=F[0][2]*v[178]+F[0][0]*v[246]+v[354]*(v[131]*v[148]+v[355])+v[44];
9573 v[45]=v[327]*v[37];
9574 v[317]=2e0*F[2][0]*v[167]+F[2][2]*v[231]+F[2][1]*v[272]+v[45];
9575 v[300]=2e0*F[1][0]*v[164]+F[1][2]*v[220]+F[1][1]*v[259]+v[45];
9576 v[275]=F[0][2]*v[209]+F[0][1]*v[246]+2e0*F[0][0]*(v[131]*v[333]+v[352])+v[45];
9577 v[46]=v[328]*v[37];
9578 v[316]=2e0*F[2][0]*v[166]+F[2][2]*v[227]+F[2][1]*v[267]+v[46];
9579 v[299]=2e0*F[1][0]*v[163]+F[1][2]*v[216]+F[1][1]*v[254]+v[46];
9580 v[274]=F[0][1]*v[241]+2e0*F[0][0]*(v[130]*v[333]+v[353])+v[46]+F[0][2]*(v[130]*v[327]+v[37]*
9581 (2e0*F[0][2]*v[18]+2e0*v[244]-2e0*v[22]*v[65]));
9582 Pmat[0][0]=F[0][0]*v[297]+F[0][2]*v[45]+F[0][1]*v[46];
9583 Pmat[0][1]=F[0][1]*v[304]+F[0][2]*v[44]+F[0][0]*v[46];
9584 Pmat[0][2]=F[0][2]*v[310]+F[0][1]*v[44]+F[0][0]*v[45];
9585 Pmat[1][0]=2e0*F[1][0]*v[43]+F[1][2]*v[45]+F[1][1]*v[46];
9586 Pmat[1][1]=2e0*F[1][1]*v[40]+F[1][2]*v[44]+F[1][0]*v[46];
9587 Pmat[1][2]=2e0*F[1][2]*v[35]+F[1][1]*v[44]+F[1][0]*v[45];
9588 Pmat[2][0]=F[2][0]*v[297]+F[2][2]*v[45]+F[2][1]*v[46];
9589 Pmat[2][1]=F[2][1]*v[304]+F[2][2]*v[44]+F[2][0]*v[46];
9590 Pmat[2][2]=F[2][2]*v[310]+F[2][1]*v[44]+F[2][0]*v[45];
9591 Amat[0][0][0][0]=v[297]+v[128]*v[351]+F[0][2]*(v[128]*v[327]-v[352])+F[0][1]*(v[128]*v[328]-v[353]
9592 );
9593 Amat[0][0][0][1]=v[274];
9594 Amat[0][0][0][2]=v[275];
9595 Amat[0][0][1][0]=v[276];
9596 Amat[0][0][1][1]=v[277];
9597 Amat[0][0][1][2]=v[278];
9598 Amat[0][0][2][0]=v[279];
9599 Amat[0][0][2][1]=v[280];
9600 Amat[0][0][2][2]=v[281];
9601 Amat[0][1][0][0]=v[274];
9602 Amat[0][1][0][1]=F[0][0]*v[241]+v[304]+v[130]*v[148]*v[354]+F[0][2]*(v[130]*v[326]-v[355]);
9603 Amat[0][1][0][2]=v[283];
9604 Amat[0][1][1][0]=v[284];
9605 Amat[0][1][1][1]=v[285];
9606 Amat[0][1][1][2]=v[286];
9607 Amat[0][1][2][0]=v[287];
9608 Amat[0][1][2][1]=v[288];
9609 Amat[0][1][2][2]=v[289];
9610 Amat[0][2][0][0]=v[275];
9611 Amat[0][2][0][1]=v[283];
9612 Amat[0][2][0][2]=F[0][1]*v[178]+F[0][0]*v[209]+v[310]+v[131]*v[138]*v[356];
9613 Amat[0][2][1][0]=v[291];
9614 Amat[0][2][1][1]=v[292];
9615 Amat[0][2][1][2]=v[293];
9616 Amat[0][2][2][0]=v[294];
9617 Amat[0][2][2][1]=v[295];
9618 Amat[0][2][2][2]=v[296];
9619 Amat[1][0][0][0]=v[276];
9620 Amat[1][0][0][1]=v[284];
9621 Amat[1][0][0][2]=v[291];
9622 Amat[1][0][1][0]=2e0*F[1][0]*v[162]+F[1][2]*v[213]+F[1][1]*v[250]+v[297];
9623 Amat[1][0][1][1]=v[299];
9624 Amat[1][0][1][2]=v[300];
9625 Amat[1][0][2][0]=v[301];
9626 Amat[1][0][2][1]=v[302];
9627 Amat[1][0][2][2]=v[303];
9628 Amat[1][1][0][0]=v[277];
9629 Amat[1][1][0][1]=v[285];
9630 Amat[1][1][0][2]=v[292];
9631 Amat[1][1][1][0]=v[299];
9632 Amat[1][1][1][1]=2e0*F[1][1]*v[153]+F[1][2]*v[183]+F[1][0]*v[254]+v[304];
9633 Amat[1][1][1][2]=v[306];
9634 Amat[1][1][2][0]=v[307];
9635 Amat[1][1][2][1]=v[308];
9636 Amat[1][1][2][2]=v[309];
9637 Amat[1][2][0][0]=v[278];
9638 Amat[1][2][0][1]=v[286];
9639 Amat[1][2][0][2]=v[293];
9640 Amat[1][2][1][0]=v[300];
9641 Amat[1][2][1][1]=v[306];
9642 Amat[1][2][1][2]=2e0*F[1][2]*v[144]+F[1][1]*v[187]+F[1][0]*v[220]+v[310];
9643 Amat[1][2][2][0]=v[312];
9644 Amat[1][2][2][1]=v[313];
9645 Amat[1][2][2][2]=v[314];
9646 Amat[2][0][0][0]=v[279];
9647 Amat[2][0][0][1]=v[287];
9648 Amat[2][0][0][2]=v[294];
9649 Amat[2][0][1][0]=v[301];
9650 Amat[2][0][1][1]=v[307];
9651 Amat[2][0][1][2]=v[312];
9652 Amat[2][0][2][0]=2e0*F[2][0]*v[165]+F[2][2]*v[224]+F[2][1]*v[263]+v[297];
9653 Amat[2][0][2][1]=v[316];
9654 Amat[2][0][2][2]=v[317];
9655 Amat[2][1][0][0]=v[280];
9656 Amat[2][1][0][1]=v[288];
9657 Amat[2][1][0][2]=v[295];
9658 Amat[2][1][1][0]=v[302];
9659 Amat[2][1][1][1]=v[308];
9660 Amat[2][1][1][2]=v[313];
9661 Amat[2][1][2][0]=v[316];
9662 Amat[2][1][2][1]=2e0*F[2][1]*v[156]+F[2][2]*v[192]+F[2][0]*v[267]+v[304];
9663 Amat[2][1][2][2]=v[319];
9664 Amat[2][2][0][0]=v[281];
9665 Amat[2][2][0][1]=v[289];
9666 Amat[2][2][0][2]=v[296];
9667 Amat[2][2][1][0]=v[303];
9668 Amat[2][2][1][1]=v[309];
9669 Amat[2][2][1][2]=v[314];
9670 Amat[2][2][2][0]=v[317];
9671 Amat[2][2][2][1]=v[319];
9672 Amat[2][2][2][2]=2e0*F[2][2]*v[147]+F[2][1]*v[196]+F[2][0]*v[231]+v[310];
9673}
9674
9675
9676/*************************************************************
9677 * AceGen 6.921 MacOSX (29 Jan 19) *
9678 * Co. J. Korelc 2013 12 Feb 19 12:06:46 *
9679 **************************************************************
9680 User : Full professional version
9681 Notebook : mr3d_C
9682 Evaluation time : 7 s Mode : Optimal
9683 Number of formulae : 190 Method: Automatic
9684 Subroutine : mr3d size: 5215
9685 Total size of Mathematica code : 5215 subexpressions
9686 Total size of C code : 10798 bytes */
9687
9688/******************* S U B R O U T I N E *********************/
9689template <class SC, class LO, class GO, class NO>
9690void FE<SC,LO,GO,NO>::mr3d(double* v,double (*E),double (*Nu),double (*C)
9691 ,double** F,double** Pmat,double**** Amat)
9692{
9693 v[366]=2e0*F[0][2];
9694 v[364]=2e0*F[0][1];
9695 v[4]=(*E)/(2e0+2e0*(*Nu));
9696 v[139]=((*C)*v[4])/2e0;
9697 v[5]=(*E)/(3e0-6e0*(*Nu));
9698 v[57]=2e0*F[0][0];
9699 v[150]=v[139]*v[57];
9700 v[66]=2e0*F[0][1];
9701 v[165]=v[139]*v[66];
9702 v[87]=2e0*F[0][2];
9703 v[167]=v[139]*v[87];
9704 v[58]=2e0*F[1][0];
9705 v[155]=v[139]*v[58];
9706 v[67]=2e0*F[1][1];
9707 v[170]=v[139]*v[67];
9708 v[88]=2e0*F[1][2];
9709 v[172]=v[139]*v[88];
9710 v[59]=2e0*F[2][0];
9711 v[159]=v[139]*v[59];
9712 v[68]=2e0*F[2][1];
9713 v[175]=v[139]*v[68];
9714 v[18]=F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1];
9715 v[345]=(v[18]*v[18]);
9716 v[89]=2e0*F[2][2];
9717 v[177]=v[139]*v[89];
9718 v[24]=F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2];
9719 v[344]=(v[24]*v[24]);
9720 v[335]=v[18]*v[24];
9721 v[22]=F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2];
9722 v[15]=Power(F[0][0],2)+Power(F[1][0],2)+Power(F[2][0],2);
9723 v[239]=-(F[2][1]*v[18]);
9724 v[236]=F[2][2]*v[18];
9725 v[228]=-(F[1][1]*v[18]);
9726 v[225]=F[1][2]*v[18];
9727 v[205]=-(F[2][0]*v[18]);
9728 v[196]=-(F[1][0]*v[18]);
9729 v[279]=F[2][1]*v[22];
9730 v[275]=-(F[2][2]*v[22]);
9731 v[266]=F[1][1]*v[22];
9732 v[262]=-(F[1][2]*v[22]);
9733 v[201]=-(F[2][0]*v[22]);
9734 v[192]=-(F[1][0]*v[22]);
9735 v[183]=-(F[0][0]*v[22]);
9736 v[20]=Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2);
9737 v[334]=-(v[20]*v[22]);
9738 v[337]=2e0*(v[334]+v[335]);
9739 v[95]=v[20]*v[89];
9740 v[93]=v[20]*v[88];
9741 v[91]=v[20]*v[87];
9742 v[140]=v[15]*v[20]-v[345];
9743 v[281]=F[2][0]*v[24];
9744 v[271]=-(F[2][2]*v[24]);
9745 v[268]=F[1][0]*v[24];
9746 v[258]=-(F[1][2]*v[24]);
9747 v[255]=F[0][0]*v[24];
9748 v[243]=-(F[0][2]*v[24]);
9749 v[233]=-(F[2][1]*v[24]);
9750 v[222]=-(F[1][1]*v[24]);
9751 v[209]=-(F[0][1]*v[24]);
9752 v[179]=v[18]*v[22]-v[15]*v[24];
9753 v[341]=2e0*v[179];
9754 v[339]=2e0*v[179];
9755 v[336]=2e0*v[179];
9756 v[38]=-(v[22]*v[22]);
9757 v[26]=Power(F[0][2],2)+Power(F[1][2],2)+Power(F[2][2],2);
9758 v[343]=v[20]*v[26]-v[344];
9759 v[361]=v[343]*v[57];
9760 v[247]=v[22]*v[24]-v[18]*v[26];
9761 v[342]=2e0*v[247];
9762 v[340]=2e0*v[247];
9763 v[338]=2e0*v[247];
9764 v[100]=v[26]*v[59];
9765 v[98]=v[26]*v[58];
9766 v[94]=v[26]*v[68];
9767 v[92]=v[26]*v[67];
9768 v[90]=v[26]*v[66];
9769 v[151]=v[15]*v[26]+v[38];
9770 v[29]=v[151]*v[20]+2e0*v[22]*v[335]-v[15]*v[344]-v[26]*v[345];
9771 v[346]=1e0/Power(v[29],2);
9772 v[33]=-2e0*v[139]-v[4]+v[5]*std::log(std::sqrt(v[29]));
9773 v[347]=v[346]*(-v[33]/2e0+v[5]/4e0);
9774 v[138]=v[347]*(F[2][1]*v[336]+F[2][0]*v[337]-v[345]*v[89]+v[15]*v[95]);
9775 v[149]=v[138]*v[140];
9776 v[137]=v[347]*(F[2][2]*v[339]+F[2][0]*v[340]+v[38]*v[68]+v[15]*v[94]);
9777 v[161]=v[137]*v[151];
9778 v[136]=v[347]*(v[100]*v[20]+F[2][2]*v[337]+F[2][1]*v[338]-v[344]*v[59]);
9779 v[174]=v[136]*v[343];
9780 v[135]=v[347]*(F[1][1]*v[336]+F[1][0]*v[337]-v[345]*v[88]+v[15]*v[93]);
9781 v[146]=v[135]*v[140];
9782 v[134]=v[347]*(F[1][2]*v[341]+F[1][0]*v[342]+v[38]*v[67]+v[15]*v[92]);
9783 v[157]=v[134]*v[151];
9784 v[133]=v[347]*(F[1][2]*v[337]+F[1][1]*v[338]-v[344]*v[58]+v[20]*v[98]);
9785 v[169]=v[133]*v[343];
9786 v[132]=v[347]*(F[0][0]*v[337]+F[0][1]*v[339]-v[345]*v[87]+v[15]*v[91]);
9787 v[131]=v[347]*(F[0][2]*v[341]+F[0][0]*v[342]+v[38]*v[66]+v[15]*v[90]);
9788 v[129]=v[347]*(F[0][2]*v[337]+F[0][1]*v[340]+v[361]);
9789 v[37]=v[33]/(2e0*v[29]);
9790 v[365]=v[37]*(2e0*v[183]+v[15]*v[87]);
9791 v[363]=v[37]*(2e0*v[243]+v[90]);
9792 v[362]=v[37]*(2e0*v[209]+v[91]);
9793 v[359]=-2e0*(F[1][0]*v[20]+v[228])*v[37];
9794 v[358]=-(v[37]*(2e0*v[196]+v[15]*v[67]));
9795 v[357]=-2e0*(F[2][0]*v[20]+v[239])*v[37];
9796 v[356]=-(v[37]*(2e0*v[205]+v[15]*v[68]));
9797 v[355]=-(v[37]*(2e0*v[262]+v[98]));
9798 v[354]=-(v[37]*(2e0*v[192]+v[15]*v[88]));
9799 v[353]=-((v[100]+2e0*v[275])*v[37]);
9800 v[352]=-(v[37]*(2e0*v[201]+v[15]*v[89]));
9801 v[351]=-(v[37]*(2e0*v[258]+v[92]));
9802 v[350]=-(v[37]*(2e0*v[222]+v[93]));
9803 v[349]=-(v[37]*(2e0*v[271]+v[94]));
9804 v[348]=-(v[37]*(2e0*v[233]+v[95]));
9805 v[283]=v[138]*v[338]+v[37]*(2e0*v[279]+2e0*v[281]-2e0*v[18]*v[89]);
9806 v[278]=-v[159]+v[137]*v[338]+v[353];
9807 v[274]=-v[175]+v[136]*v[338]+v[349];
9808 v[270]=v[135]*v[338]+v[37]*(2e0*v[266]+2e0*v[268]-2e0*v[18]*v[88]);
9809 v[265]=-v[155]+v[134]*v[338]+v[355];
9810 v[261]=-v[170]+v[133]*v[338]+v[351];
9811 v[257]=v[132]*v[338]+v[37]*(2e0*F[0][1]*v[22]+2e0*v[255]-2e0*v[18]*v[87]);
9812 v[252]=-v[150]+v[131]*v[338]+2e0*(F[0][2]*v[22]-F[0][0]*v[26])*v[37];
9813 v[242]=-v[159]+v[138]*v[337]+v[357];
9814 v[238]=v[137]*v[337]+v[37]*(2e0*v[236]+2e0*v[281]-2e0*v[22]*v[68]);
9815 v[235]=-v[177]+v[136]*v[337]+v[348];
9816 v[312]=2e0*F[1][0]*v[174]+F[1][2]*v[235]+F[1][1]*v[274];
9817 v[290]=2e0*F[0][0]*v[174]+F[0][2]*v[235]+F[0][1]*v[274];
9818 v[231]=-v[155]+v[135]*v[337]+v[359];
9819 v[227]=v[134]*v[337]+v[37]*(2e0*v[225]+2e0*v[268]-2e0*v[22]*v[67]);
9820 v[224]=-v[172]+v[133]*v[337]+v[350];
9821 v[287]=2e0*F[0][0]*v[169]+F[0][2]*v[224]+F[0][1]*v[261];
9822 v[220]=-v[150]+v[132]*v[337]+2e0*(F[0][1]*v[18]-F[0][0]*v[20])*v[37];
9823 v[207]=-v[175]+v[138]*v[336]+v[356];
9824 v[325]=2e0*F[1][2]*v[149]+F[1][1]*v[207]+F[1][0]*v[242];
9825 v[307]=2e0*F[0][2]*v[149]+F[0][1]*v[207]+F[0][0]*v[242];
9826 v[203]=-v[177]+v[137]*v[336]+v[352];
9827 v[319]=2e0*F[1][1]*v[161]+F[1][2]*v[203]+F[1][0]*v[278];
9828 v[299]=2e0*F[0][1]*v[161]+F[0][2]*v[203]+F[0][0]*v[278];
9829 v[199]=v[136]*v[336]+v[37]*(2e0*v[236]+2e0*v[279]-2e0*v[24]*v[59]);
9830 v[198]=-v[170]+v[135]*v[336]+v[358];
9831 v[304]=2e0*F[0][2]*v[146]+F[0][1]*v[198]+F[0][0]*v[231];
9832 v[194]=-v[172]+v[134]*v[336]+v[354];
9833 v[296]=2e0*F[0][1]*v[157]+F[0][2]*v[194]+F[0][0]*v[265];
9834 v[190]=v[133]*v[336]+v[37]*(2e0*v[225]+2e0*v[266]-2e0*v[24]*v[58]);
9835 v[189]=-v[165]+v[132]*v[336]+2e0*(-(F[0][1]*v[15])+F[0][0]*v[18])*v[37];
9836 v[178]=v[177]+v[138]*v[343]-v[348];
9837 v[314]=2e0*F[1][0]*v[178]+F[1][2]*v[242]+F[1][1]*v[283];
9838 v[292]=2e0*F[0][0]*v[178]+F[0][2]*v[242]+F[0][1]*v[283];
9839 v[176]=v[175]+v[137]*v[343]-v[349];
9840 v[313]=2e0*F[1][0]*v[176]+F[1][2]*v[238]+F[1][1]*v[278];
9841 v[291]=2e0*F[0][0]*v[176]+F[0][2]*v[238]+F[0][1]*v[278];
9842 v[173]=v[172]+v[135]*v[343]-v[350];
9843 v[289]=2e0*F[0][0]*v[173]+F[0][2]*v[231]+F[0][1]*v[270];
9844 v[171]=v[170]+v[134]*v[343]-v[351];
9845 v[288]=2e0*F[0][0]*v[171]+F[0][2]*v[227]+F[0][1]*v[265];
9846 v[162]=v[138]*v[151]+v[177]-v[352];
9847 v[320]=2e0*F[1][1]*v[162]+F[1][2]*v[207]+F[1][0]*v[283];
9848 v[300]=2e0*F[0][1]*v[162]+F[0][2]*v[207]+F[0][0]*v[283];
9849 v[160]=v[136]*v[151]+v[159]-v[353];
9850 v[318]=2e0*F[1][1]*v[160]+F[1][2]*v[199]+F[1][0]*v[274];
9851 v[298]=2e0*F[0][1]*v[160]+F[0][2]*v[199]+F[0][0]*v[274];
9852 v[158]=v[135]*v[151]+v[172]-v[354];
9853 v[297]=2e0*F[0][1]*v[158]+F[0][2]*v[198]+F[0][0]*v[270];
9854 v[295]=F[0][2]*v[190]+F[0][0]*v[261]+2e0*F[0][1]*(v[133]*v[151]+v[155]-v[355]);
9855 v[148]=v[137]*v[140]+v[175]-v[356];
9856 v[324]=2e0*F[1][2]*v[148]+F[1][1]*v[203]+F[1][0]*v[238];
9857 v[306]=2e0*F[0][2]*v[148]+F[0][1]*v[203]+F[0][0]*v[238];
9858 v[147]=v[136]*v[140]+v[159]-v[357];
9859 v[323]=2e0*F[1][2]*v[147]+F[1][1]*v[199]+F[1][0]*v[235];
9860 v[305]=2e0*F[0][2]*v[147]+F[0][1]*v[199]+F[0][0]*v[235];
9861 v[303]=F[0][1]*v[194]+F[0][0]*v[227]+2e0*F[0][2]*(v[134]*v[140]+v[170]-v[358]);
9862 v[302]=F[0][1]*v[190]+F[0][0]*v[224]+(v[133]*v[140]+v[155]-v[359])*v[366];
9863 v[36]=v[140]*v[37]+((1e0+(*C)*(-1e0+v[15]+v[20]))*v[4])/2e0;
9864 v[321]=2e0*v[36];
9865 v[40]=v[151]*v[37]+((1e0+(*C)*(-1e0+v[15]+v[26]))*v[4])/2e0;
9866 v[315]=2e0*v[40];
9867 v[43]=v[343]*v[37]+((1e0+(*C)*(-1e0+v[20]+v[26]))*v[4])/2e0;
9868 v[308]=2e0*v[43];
9869 v[45]=-2e0*v[139]*v[24]+v[336]*v[37];
9870 v[330]=2e0*F[2][1]*v[162]+F[2][2]*v[207]+F[2][0]*v[283]+v[45];
9871 v[317]=2e0*F[1][1]*v[158]+F[1][2]*v[198]+F[1][0]*v[270]+v[45];
9872 v[294]=F[0][2]*v[189]+F[0][0]*v[257]+v[364]*(v[132]*v[151]+v[167]+v[365])+v[45];
9873 v[46]=-2e0*v[139]*v[22]+v[337]*v[37];
9874 v[328]=2e0*F[2][0]*v[178]+F[2][2]*v[242]+F[2][1]*v[283]+v[46];
9875 v[311]=2e0*F[1][0]*v[173]+F[1][2]*v[231]+F[1][1]*v[270]+v[46];
9876 v[286]=F[0][2]*v[220]+F[0][1]*v[257]+2e0*F[0][0]*(v[167]+v[132]*v[343]+v[362])+v[46];
9877 v[47]=-2e0*v[139]*v[18]+v[338]*v[37];
9878 v[327]=2e0*F[2][0]*v[176]+F[2][2]*v[238]+F[2][1]*v[278]+v[47];
9879 v[310]=2e0*F[1][0]*v[171]+F[1][2]*v[227]+F[1][1]*v[265]+v[47];
9880 v[285]=F[0][1]*v[252]+2e0*F[0][0]*(v[165]+v[131]*v[343]+v[363])+v[47]+F[0][2]*(v[131]*v[337]+v[37]*
9881 (2e0*F[0][2]*v[18]+2e0*v[255]-2e0*v[22]*v[66]));
9882 Pmat[0][0]=F[0][0]*v[308]+F[0][2]*v[46]+F[0][1]*v[47];
9883 Pmat[0][1]=F[0][1]*v[315]+F[0][2]*v[45]+F[0][0]*v[47];
9884 Pmat[0][2]=F[0][2]*v[321]+F[0][1]*v[45]+F[0][0]*v[46];
9885 Pmat[1][0]=2e0*F[1][0]*v[43]+F[1][2]*v[46]+F[1][1]*v[47];
9886 Pmat[1][1]=2e0*F[1][1]*v[40]+F[1][2]*v[45]+F[1][0]*v[47];
9887 Pmat[1][2]=2e0*F[1][2]*v[36]+F[1][1]*v[45]+F[1][0]*v[46];
9888 Pmat[2][0]=F[2][0]*v[308]+F[2][2]*v[46]+F[2][1]*v[47];
9889 Pmat[2][1]=F[2][1]*v[315]+F[2][2]*v[45]+F[2][0]*v[47];
9890 Pmat[2][2]=F[2][2]*v[321]+F[2][1]*v[45]+F[2][0]*v[46];
9891 Amat[0][0][0][0]=v[308]+v[129]*v[361]+F[0][2]*(-v[167]+v[129]*v[337]-v[362])+F[0][1]*(-v[165]
9892 +v[129]*v[338]-v[363]);
9893 Amat[0][0][0][1]=v[285];
9894 Amat[0][0][0][2]=v[286];
9895 Amat[0][0][1][0]=v[287];
9896 Amat[0][0][1][1]=v[288];
9897 Amat[0][0][1][2]=v[289];
9898 Amat[0][0][2][0]=v[290];
9899 Amat[0][0][2][1]=v[291];
9900 Amat[0][0][2][2]=v[292];
9901 Amat[0][1][0][0]=v[285];
9902 Amat[0][1][0][1]=F[0][0]*v[252]+v[315]+v[131]*v[151]*v[364]+F[0][2]*(-v[167]+v[131]*v[336]-v[365]);
9903 Amat[0][1][0][2]=v[294];
9904 Amat[0][1][1][0]=v[295];
9905 Amat[0][1][1][1]=v[296];
9906 Amat[0][1][1][2]=v[297];
9907 Amat[0][1][2][0]=v[298];
9908 Amat[0][1][2][1]=v[299];
9909 Amat[0][1][2][2]=v[300];
9910 Amat[0][2][0][0]=v[286];
9911 Amat[0][2][0][1]=v[294];
9912 Amat[0][2][0][2]=F[0][1]*v[189]+F[0][0]*v[220]+v[321]+v[132]*v[140]*v[366];
9913 Amat[0][2][1][0]=v[302];
9914 Amat[0][2][1][1]=v[303];
9915 Amat[0][2][1][2]=v[304];
9916 Amat[0][2][2][0]=v[305];
9917 Amat[0][2][2][1]=v[306];
9918 Amat[0][2][2][2]=v[307];
9919 Amat[1][0][0][0]=v[287];
9920 Amat[1][0][0][1]=v[295];
9921 Amat[1][0][0][2]=v[302];
9922 Amat[1][0][1][0]=2e0*F[1][0]*v[169]+F[1][2]*v[224]+F[1][1]*v[261]+v[308];
9923 Amat[1][0][1][1]=v[310];
9924 Amat[1][0][1][2]=v[311];
9925 Amat[1][0][2][0]=v[312];
9926 Amat[1][0][2][1]=v[313];
9927 Amat[1][0][2][2]=v[314];
9928 Amat[1][1][0][0]=v[288];
9929 Amat[1][1][0][1]=v[296];
9930 Amat[1][1][0][2]=v[303];
9931 Amat[1][1][1][0]=v[310];
9932 Amat[1][1][1][1]=2e0*F[1][1]*v[157]+F[1][2]*v[194]+F[1][0]*v[265]+v[315];
9933 Amat[1][1][1][2]=v[317];
9934 Amat[1][1][2][0]=v[318];
9935 Amat[1][1][2][1]=v[319];
9936 Amat[1][1][2][2]=v[320];
9937 Amat[1][2][0][0]=v[289];
9938 Amat[1][2][0][1]=v[297];
9939 Amat[1][2][0][2]=v[304];
9940 Amat[1][2][1][0]=v[311];
9941 Amat[1][2][1][1]=v[317];
9942 Amat[1][2][1][2]=2e0*F[1][2]*v[146]+F[1][1]*v[198]+F[1][0]*v[231]+v[321];
9943 Amat[1][2][2][0]=v[323];
9944 Amat[1][2][2][1]=v[324];
9945 Amat[1][2][2][2]=v[325];
9946 Amat[2][0][0][0]=v[290];
9947 Amat[2][0][0][1]=v[298];
9948 Amat[2][0][0][2]=v[305];
9949 Amat[2][0][1][0]=v[312];
9950 Amat[2][0][1][1]=v[318];
9951 Amat[2][0][1][2]=v[323];
9952 Amat[2][0][2][0]=2e0*F[2][0]*v[174]+F[2][2]*v[235]+F[2][1]*v[274]+v[308];
9953 Amat[2][0][2][1]=v[327];
9954 Amat[2][0][2][2]=v[328];
9955 Amat[2][1][0][0]=v[291];
9956 Amat[2][1][0][1]=v[299];
9957 Amat[2][1][0][2]=v[306];
9958 Amat[2][1][1][0]=v[313];
9959 Amat[2][1][1][1]=v[319];
9960 Amat[2][1][1][2]=v[324];
9961 Amat[2][1][2][0]=v[327];
9962 Amat[2][1][2][1]=2e0*F[2][1]*v[161]+F[2][2]*v[203]+F[2][0]*v[278]+v[315];
9963 Amat[2][1][2][2]=v[330];
9964 Amat[2][2][0][0]=v[292];
9965 Amat[2][2][0][1]=v[300];
9966 Amat[2][2][0][2]=v[307];
9967 Amat[2][2][1][0]=v[314];
9968 Amat[2][2][1][1]=v[320];
9969 Amat[2][2][1][2]=v[325];
9970 Amat[2][2][2][0]=v[328];
9971 Amat[2][2][2][1]=v[330];
9972 Amat[2][2][2][2]=2e0*F[2][2]*v[149]+F[2][1]*v[207]+F[2][0]*v[242]+v[321];
9973};
9974
9975
9976/*************************************************************
9977 * AceGen 6.921 MacOSX (29 Jan 19) *
9978 * Co. J. Korelc 2013 17 Jul 19 15:09:55 *
9979 **************************************************************
9980 User : Full professional version
9981 Notebook : st_venant_kirchhoff_3d
9982 Evaluation time : 3 s Mode : Optimal
9983 Number of formulae : 91 Method: Automatic
9984 Subroutine : stvk3d size: 2846
9985 Total size of Mathematica code : 2846 subexpressions
9986 Total size of C code : 5830 bytes */
9987
9988/******************* S U B R O U T I N E *********************/
9989template <class SC, class LO, class GO, class NO>
9990void FE<SC,LO,GO,NO>::stvk3d(double* v,double (*lam),double (*mue),double** F
9991 ,double** Pmat,double**** Amat)
9992{
9993 v[169]=Power(F[0][0],2);
9994 v[168]=2e0*(*mue);
9995 v[167]=Power(F[0][2],2);
9996 v[166]=F[2][2]*(*mue);
9997 v[165]=F[2][1]*(*mue);
9998 v[164]=F[2][0]*(*mue);
9999 v[163]=F[1][2]*(*mue);
10000 v[162]=F[1][1]*(*mue);
10001 v[161]=F[1][0]*(*mue);
10002 v[88]=F[0][0]*(*mue);
10003 v[116]=F[0][0]*v[88];
10004 v[70]=F[0][1]*(*lam);
10005 v[93]=F[0][1]*(*mue);
10006 v[117]=F[0][1]*v[93];
10007 v[71]=F[0][2]*(*lam);
10008 v[105]=(*mue)*v[167];
10009 v[72]=F[1][0]*(*lam);
10010 v[85]=2e0*v[161]+v[72];
10011 v[142]=F[1][0]*v[161];
10012 v[121]=F[0][0]*v[161];
10013 v[73]=F[1][1]*(*lam);
10014 v[100]=F[0][1]*v[161]+F[0][0]*v[73];
10015 v[82]=2e0*v[162]+v[73];
10016 v[143]=F[1][1]*v[162];
10017 v[122]=F[0][1]*v[162];
10018 v[108]=F[0][0]*v[162]+F[0][1]*v[72];
10019 v[74]=F[1][2]*(*lam);
10020 v[111]=F[0][2]*v[162]+F[0][1]*v[74];
10021 v[101]=F[0][2]*v[161]+F[0][0]*v[74];
10022 v[79]=2e0*v[163]+v[74];
10023 v[123]=v[121]+v[122]+F[0][2]*v[79];
10024 v[135]=F[1][2]*v[163];
10025 v[120]=F[0][1]*v[163]+F[0][2]*v[73];
10026 v[119]=F[0][0]*v[163]+F[0][2]*v[72];
10027 v[109]=F[0][2]*v[163];
10028 v[110]=v[109]+v[121]+F[0][1]*v[82];
10029 v[99]=v[109]+v[122]+F[0][0]*v[85];
10030 v[75]=F[2][0]*(*lam);
10031 v[86]=2e0*v[164]+v[75];
10032 v[156]=F[2][0]*v[164];
10033 v[147]=F[1][0]*v[164];
10034 v[126]=F[0][0]*v[164];
10035 v[76]=F[2][1]*(*lam);
10036 v[133]=F[1][1]*v[164]+F[1][0]*v[76];
10037 v[103]=F[0][1]*v[164]+F[0][0]*v[76];
10038 v[83]=2e0*v[165]+v[76];
10039 v[157]=F[2][1]*v[165];
10040 v[148]=F[1][1]*v[165];
10041 v[138]=F[1][0]*v[165]+F[1][1]*v[75];
10042 v[127]=F[0][1]*v[165];
10043 v[112]=F[0][0]*v[165]+F[0][1]*v[75];
10044 v[77]=F[2][2]*(*lam);
10045 v[141]=F[1][2]*v[165]+F[1][1]*v[77];
10046 v[134]=F[1][2]*v[164]+F[1][0]*v[77];
10047 v[115]=F[0][2]*v[165]+F[0][1]*v[77];
10048 v[104]=F[0][2]*v[164]+F[0][0]*v[77];
10049 v[80]=2e0*v[166]+v[77];
10050 v[149]=v[147]+v[148]+F[1][2]*v[80];
10051 v[128]=v[126]+v[127]+F[0][2]*v[80];
10052 v[153]=F[2][2]*v[166];
10053 v[146]=F[1][1]*v[166]+F[1][2]*v[76];
10054 v[145]=F[1][0]*v[166]+F[1][2]*v[75];
10055 v[139]=F[1][2]*v[166];
10056 v[140]=v[139]+v[147]+F[1][1]*v[83];
10057 v[132]=v[139]+v[148]+F[1][0]*v[86];
10058 v[125]=F[0][1]*v[166]+F[0][2]*v[76];
10059 v[124]=F[0][0]*v[166]+F[0][2]*v[75];
10060 v[113]=F[0][2]*v[166];
10061 v[114]=v[113]+v[126]+F[0][1]*v[83];
10062 v[102]=v[113]+v[127]+F[0][0]*v[86];
10063 v[24]=(-1e0+Power(F[1][0],2)+Power(F[2][0],2)+v[169])/2e0;
10064 v[28]=(-1e0+Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2))/2e0;
10065 v[32]=(-1e0+Power(F[1][2],2)+Power(F[2][2],2)+v[167])/2e0;
10066 v[36]=(*lam)*(v[24]+v[28]+v[32]);
10067 v[35]=2e0*(*mue)*v[32]+v[36];
10068 v[37]=2e0*(*mue)*v[28]+v[36];
10069 v[38]=2e0*(*mue)*v[24]+v[36];
10070 v[39]=(F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2])*(*mue);
10071 v[152]=F[2][2]*v[164]+v[39]+F[2][0]*v[77];
10072 v[131]=F[1][2]*v[161]+v[39]+F[1][0]*v[74];
10073 v[98]=v[39]+F[0][0]*v[71]+F[0][2]*v[88];
10074 v[40]=(F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2])*(*mue);
10075 v[155]=F[2][2]*v[165]+v[40]+F[2][1]*v[77];
10076 v[137]=F[1][2]*v[162]+v[40]+F[1][1]*v[74];
10077 v[107]=v[40]+F[0][1]*v[71]+F[0][2]*v[93];
10078 v[41]=(F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1])*(*mue);
10079 v[151]=F[2][1]*v[164]+v[41]+F[2][0]*v[76];
10080 v[130]=F[1][1]*v[161]+v[41]+F[1][0]*v[73];
10081 v[97]=v[41]+F[0][0]*v[70]+F[0][1]*v[88];
10082 Pmat[0][0]=F[0][0]*v[38]+F[0][2]*v[39]+F[0][1]*v[41];
10083 Pmat[0][1]=F[0][1]*v[37]+F[0][2]*v[40]+F[0][0]*v[41];
10084 Pmat[0][2]=F[0][2]*v[35]+F[0][0]*v[39]+F[0][1]*v[40];
10085 Pmat[1][0]=F[1][0]*v[38]+F[1][2]*v[39]+F[1][1]*v[41];
10086 Pmat[1][1]=F[1][1]*v[37]+F[1][2]*v[40]+F[1][0]*v[41];
10087 Pmat[1][2]=F[1][2]*v[35]+F[1][0]*v[39]+F[1][1]*v[40];
10088 Pmat[2][0]=F[2][0]*v[38]+F[2][2]*v[39]+F[2][1]*v[41];
10089 Pmat[2][1]=F[2][1]*v[37]+F[2][2]*v[40]+F[2][0]*v[41];
10090 Pmat[2][2]=F[2][2]*v[35]+F[2][0]*v[39]+F[2][1]*v[40];
10091 Amat[0][0][0][0]=v[105]+v[117]+((*lam)+v[168])*v[169]+v[38];
10092 Amat[0][0][0][1]=v[97];
10093 Amat[0][0][0][2]=v[98];
10094 Amat[0][0][1][0]=v[99];
10095 Amat[0][0][1][1]=v[100];
10096 Amat[0][0][1][2]=v[101];
10097 Amat[0][0][2][0]=v[102];
10098 Amat[0][0][2][1]=v[103];
10099 Amat[0][0][2][2]=v[104];
10100 Amat[0][1][0][0]=v[97];
10101 Amat[0][1][0][1]=v[105]+v[116]+v[37]+F[0][1]*(v[70]+2e0*v[93]);
10102 Amat[0][1][0][2]=v[107];
10103 Amat[0][1][1][0]=v[108];
10104 Amat[0][1][1][1]=v[110];
10105 Amat[0][1][1][2]=v[111];
10106 Amat[0][1][2][0]=v[112];
10107 Amat[0][1][2][1]=v[114];
10108 Amat[0][1][2][2]=v[115];
10109 Amat[0][2][0][0]=v[98];
10110 Amat[0][2][0][1]=v[107];
10111 Amat[0][2][0][2]=v[116]+v[117]+v[35]+F[0][2]*(F[0][2]*v[168]+v[71]);
10112 Amat[0][2][1][0]=v[119];
10113 Amat[0][2][1][1]=v[120];
10114 Amat[0][2][1][2]=v[123];
10115 Amat[0][2][2][0]=v[124];
10116 Amat[0][2][2][1]=v[125];
10117 Amat[0][2][2][2]=v[128];
10118 Amat[1][0][0][0]=v[99];
10119 Amat[1][0][0][1]=v[108];
10120 Amat[1][0][0][2]=v[119];
10121 Amat[1][0][1][0]=v[135]+v[143]+v[38]+F[1][0]*v[85];
10122 Amat[1][0][1][1]=v[130];
10123 Amat[1][0][1][2]=v[131];
10124 Amat[1][0][2][0]=v[132];
10125 Amat[1][0][2][1]=v[133];
10126 Amat[1][0][2][2]=v[134];
10127 Amat[1][1][0][0]=v[100];
10128 Amat[1][1][0][1]=v[110];
10129 Amat[1][1][0][2]=v[120];
10130 Amat[1][1][1][0]=v[130];
10131 Amat[1][1][1][1]=v[135]+v[142]+v[37]+F[1][1]*v[82];
10132 Amat[1][1][1][2]=v[137];
10133 Amat[1][1][2][0]=v[138];
10134 Amat[1][1][2][1]=v[140];
10135 Amat[1][1][2][2]=v[141];
10136 Amat[1][2][0][0]=v[101];
10137 Amat[1][2][0][1]=v[111];
10138 Amat[1][2][0][2]=v[123];
10139 Amat[1][2][1][0]=v[131];
10140 Amat[1][2][1][1]=v[137];
10141 Amat[1][2][1][2]=v[142]+v[143]+v[35]+F[1][2]*v[79];
10142 Amat[1][2][2][0]=v[145];
10143 Amat[1][2][2][1]=v[146];
10144 Amat[1][2][2][2]=v[149];
10145 Amat[2][0][0][0]=v[102];
10146 Amat[2][0][0][1]=v[112];
10147 Amat[2][0][0][2]=v[124];
10148 Amat[2][0][1][0]=v[132];
10149 Amat[2][0][1][1]=v[138];
10150 Amat[2][0][1][2]=v[145];
10151 Amat[2][0][2][0]=v[153]+v[157]+v[38]+F[2][0]*v[86];
10152 Amat[2][0][2][1]=v[151];
10153 Amat[2][0][2][2]=v[152];
10154 Amat[2][1][0][0]=v[103];
10155 Amat[2][1][0][1]=v[114];
10156 Amat[2][1][0][2]=v[125];
10157 Amat[2][1][1][0]=v[133];
10158 Amat[2][1][1][1]=v[140];
10159 Amat[2][1][1][2]=v[146];
10160 Amat[2][1][2][0]=v[151];
10161 Amat[2][1][2][1]=v[153]+v[156]+v[37]+F[2][1]*v[83];
10162 Amat[2][1][2][2]=v[155];
10163 Amat[2][2][0][0]=v[104];
10164 Amat[2][2][0][1]=v[115];
10165 Amat[2][2][0][2]=v[128];
10166 Amat[2][2][1][0]=v[134];
10167 Amat[2][2][1][1]=v[141];
10168 Amat[2][2][1][2]=v[149];
10169 Amat[2][2][2][0]=v[152];
10170 Amat[2][2][2][1]=v[155];
10171 Amat[2][2][2][2]=v[156]+v[157]+v[35]+F[2][2]*v[80];
10172};
10173/*************************************************************
10174 * AceGen 6.921 MacOSX (29 Jan 19) *
10175 * Co. J. Korelc 2013 17 Jul 19 16:01:42 *
10176 **************************************************************
10177 User : Full professional version
10178 Notebook : st_venant_kirchhoff_2d
10179 Evaluation time : 1 s Mode : Optimal
10180 Number of formulae : 25 Method: Automatic
10181 Subroutine : stvk2d size: 772
10182 Total size of Mathematica code : 772 subexpressions
10183 Total size of C code : 1672 bytes */
10184
10185
10186/******************* S U B R O U T I N E *********************/
10187template <class SC, class LO, class GO, class NO>
10188void FE<SC,LO,GO,NO>::stvk2d(double* v, double (*lam),double (*mue),double** F
10189 ,double** Pmat,double**** Amat)
10190{
10191 v[43]=F[0][0]*F[1][0];
10192 v[42]=F[0][1]*F[1][1];
10193 v[37]=Power(F[0][0],2);
10194 v[12]=F[0][0]/2e0;
10195 v[36]=Power(F[0][1],2);
10196 v[34]=F[0][0]*F[0][1];
10197 v[11]=F[0][1]/2e0;
10198 v[27]=Power(F[1][0],2);
10199 v[31]=-1e0+v[27]+v[37];
10200 v[14]=F[1][0]/2e0;
10201 v[25]=Power(F[1][1],2);
10202 v[26]=-1e0+v[25]+v[36];
10203 v[23]=F[1][0]*F[1][1];
10204 v[22]=v[23]+v[34];
10205 v[35]=(*lam)*v[34]+(*mue)*(v[22]+v[34]);
10206 v[24]=(*lam)*v[23]+(*mue)*(v[22]+v[23]);
10207 v[21]=(*lam)*v[42]+2e0*(*mue)*(2e0*v[12]*v[14]+v[42]);
10208 v[20]=F[0][0]*F[1][1]*(*lam)+4e0*(*mue)*v[11]*v[14];
10209 v[13]=F[1][1]/2e0;
10210 v[30]=F[0][1]*F[1][0]*(*lam)+4e0*(*mue)*v[12]*v[13];
10211 v[29]=(*lam)*v[43]+2e0*(*mue)*(2e0*v[11]*v[13]+v[43]);
10212 v[44]=2e0*v[22];
10213 v[32]=((*lam)*(v[26]+v[31]))/2e0;
10214 Pmat[0][0]=F[0][0]*v[32]+(*mue)*(F[0][0]*v[31]+v[11]*v[44]);
10215 Pmat[0][1]=F[0][1]*v[32]+(*mue)*(F[0][1]*v[26]+v[12]*v[44]);
10216 Pmat[1][0]=F[1][0]*v[32]+(*mue)*(F[1][0]*v[31]+v[13]*v[44]);
10217 Pmat[1][1]=F[1][1]*v[32]+(*mue)*(F[1][1]*v[26]+v[14]*v[44]);
10218 Amat[0][0][0][0]=v[32]+(*lam)*v[37]+(*mue)*(v[31]+v[36]+2e0*v[37]);
10219 Amat[0][0][0][1]=v[35];
10220 Amat[0][0][1][0]=v[29];
10221 Amat[0][0][1][1]=v[20];
10222 Amat[0][1][0][0]=v[35];
10223 Amat[0][1][0][1]=v[32]+(*lam)*v[36]+(*mue)*(v[26]+2e0*v[36]+v[37]);
10224 Amat[0][1][1][0]=v[30];
10225 Amat[0][1][1][1]=v[21];
10226 Amat[1][0][0][0]=v[29];
10227 Amat[1][0][0][1]=v[30];
10228 Amat[1][0][1][0]=(*lam)*v[27]+(*mue)*(v[25]+2e0*v[27]+v[31])+v[32];
10229 Amat[1][0][1][1]=v[24];
10230 Amat[1][1][0][0]=v[20];
10231 Amat[1][1][0][1]=v[21];
10232 Amat[1][1][1][0]=v[24];
10233 Amat[1][1][1][1]=(*lam)*v[25]+(*mue)*(2e0*v[25]+v[26]+v[27])+v[32];
10234};
10235
10236
10237/*************************************************************
10238 * AceGen 6.818 Linux (13 Sep 17) *
10239 * Co. J. Korelc 2013 21 May 19 12:35:39 *
10240 **************************************************************
10241 User : Full professional version
10242 Notebook : T2_TPM_up_LE_Iso_Gal
10243 Evaluation time : 6 s Mode : Optimal
10244 Number of formulae : 324 Method: Automatic
10245 Subroutine : SKR size: 3659
10246 Subroutine : SPP size: 2226
10247 Total size of Mathematica code : 5885 subexpressions
10248 Total size of C code : 16126 bytes */
10249template <class SC, class LO, class GO, class NO>
10250void FE<SC,LO,GO,NO>::SMTSetElSpecBiot(ElementSpec *es,int *idata,int ic,int ng, vec_dbl_Type& paraVec)
10251{
10252 int dim = domainVec_[0]->getDimension();
10253 int intc,nd,i;FILE *SMSFile;
10254 static int pn[24]={1, 4, 2, 5, 3, 6, 0, 1, 4, 6, -1, 4, 2, 5, -1, 6, 4, 5, -1, 6, 5, 3, -1, 0};
10255 static int dof[9]={2, 2, 2, 2, 2, 2, 1, 1, 1};
10256 static int nsto[9]={0, 0, 0, 0, 0, 0, 0, 0, 0};
10257
10258 static int ndat[9]={0, 0, 0, 0, 0, 0, 0, 0, 0};
10259
10260 static char *nid[]={"D","D","D","D","D","D",
10261 "p","p","p"};
10262
10263
10264 //Name der Daten in es->Data
10265 static char *gdcs[]={ "$[Gamma]$NM -Newmark Parameter",
10266 "$[Beta]$NM -Newmark Parameter",
10267 "ns0s -initial volume fraction solid",
10268 "kL -Darcy parameter",
10269 "E -Youngs modulus",
10270 "$[Nu]$ -Poissons Ratio"};
10271
10272 //soll in es->Data
10273// static double defd[]={ gamma,
10274// beta,
10275// ns_init_solid,
10276// darcyPara,
10277// youngsModulus,
10278// poissonRatio,
10279// 0e0 /*this is not used*/};
10280 static char *gpcs[]={""};
10281 static char *npcs[]={"p","u1","u2","u3","$[Sigma]$11","$[Sigma]$22",
10282 "$[Sigma]$33","$[Sigma]$12","$[Sigma]$23","$[Sigma]$31","seepage1","seepage2"};
10283 static char *sname[]={""};
10284 static char *idname[]={""};
10285 static int idindex[1];
10286 static char *rdname[]={""};
10287 static char *cswitch[]={""};
10288 static int iswitch[1]={0};
10289 static double dswitch[1]={0e0};
10290 static int rdindex[1];
10291 static int nspecs[9];
10292 static double version[3]={6.818,6.818,11.1};
10293 static double pnweights[9]={1e0,1e0,1e0,1e0,1e0,1e0,
10294 0e0,0e0,0e0};
10295 //bestimmt die Koordinaten fuer das Refernezelement
10296 static double rnodes[27]={ 1e0,0e0,0e0,
10297 0e0,1e0,0e0,
10298 0e0,0e0,0e0,
10299 0.5e0,0e0,0e0,
10300 0.5e0,0.5e0,0e0,
10301 0e0,0.5e0,0e0,
10302 1e0,0e0,0e0,
10303 0e0,1e0,0e0,
10304 0e0,0e0,0e0 };
10305
10306 es->ReferenceNodes=rnodes;
10307 if(ng==-1) es->Data= &paraVec[0];
10308 es->id.NoDomainData=6;
10309 es->Code="T2_TPM_up_LE_Iso_Gal";
10310 es->Version=version;
10311 es->MainTitle="";
10312 es->SubTitle="";
10313 es->SubSubTitle="";
10314 es->Bibliography="";
10315 //WorkingVectoSize fehlt hier. Wird fuer v[WorkingVectorSize] benoetigt.
10316 es->id.NoDimensions = dim ;
10317 es->id.NoDOFGlobal=15; //anpassen
10318 es->id.NoDOFCondense=0;
10319 es->id.NoNodes=9;//anpassen
10320 es->id.NoSegmentPoints=23;//was tut das?
10321 es->Segments=pn;
10322 es->PostNodeWeights=pnweights;
10323 es->id.NoIntSwitch=0;//was tut das?
10324 es->IntSwitch=iswitch;//was tut das?
10325 es->id.DemoLimitation=0;//was tut das?
10326 es->id.NoDoubleSwitch=0;//was tut das?
10327 es->DoubleSwitch=dswitch;//was tut das?
10328 es->id.NoCharSwitch=0;//was tut das?
10329 es->CharSwitch=cswitch;//was tut das?
10330 es->DOFGlobal=dof;
10331 es->NodeID=nid;
10332 es->id.NoGPostData=0;
10333 es->id.NoNPostData=12;//was tut das?
10334 es->id.SymmetricTangent=0;
10335 es->id.CreateDummyNodes=0;
10336 es->id.PostIterationCall=0;//was tut das?
10337 es->id.DOFScaling=0;//was tut das?
10338 es->Topology="XX";
10339 es->DomainDataNames=gdcs;//warum? dies sind die Parameter
10340 es->GPostNames=gpcs;
10341 es->NPostNames=npcs;
10342 es->AdditionalNodes="{}&";
10343 es->AdditionalGraphics="{}&";
10344 es->MMAInitialisation=MMAInitialisationCode;
10345 es->MMANextStep="";
10346 es->MMAStepBack="";
10347 es->MMAPreIteration="";
10348 es->IDataNames=idname;
10349 es->IDataIndex=idindex;
10350 es->RDataNames=rdname;
10351 es->RDataIndex=rdindex;
10352 es->id.NoIData=0;
10353 es->id.NoRData=0;
10354 es->id.ShapeSensitivity=0;
10355 es->id.EBCSensitivity=0;
10356 es->id.SensitivityOrder=0;
10357 es->id.NoSensNames=0;
10358 es->SensitivityNames=sname;
10359 es->NodeSpecs=nspecs;
10360 //es->user.SPP=SPP; //not used atm
10361// es->user.SKR=SKR; //do we need this?
10362
10363 es->id.DefaultIntegrationCode=35;
10364 if(ic==-1){intc=35;} else {intc=ic;};
10365 es->id.IntCode=intc;
10366 // we should know the suitable length of idata
10367 es->IntPoints = SMTMultiIntPoints(&intc,idata,&es->id.NoIntPoints,
10368 &es->id.NoIntPointsA,&es->id.NoIntPointsB,&es->id.NoIntPointsC,1);
10369 es->id.NoAdditionalData=(int)(0);
10370 //Laenge von NoTimeStorage muss zu hp bzw. ht passen, siehe ed->hp und ed->ht in SKR
10371 es->id.NoTimeStorage=(int)(24);
10372 es->id.NoElementData=(int)(0);
10373
10374 es->NoNodeStorage=nsto;es->NoNodeData=ndat;
10375
10376};
10377
10378template <class SC, class LO, class GO, class NO>
10379void FE<SC,LO,GO,NO>::SMTSetElSpecBiotStVK(ElementSpec *es,int *idata,int ic,int ng, vec_dbl_Type& paraVec)
10380{
10381
10382 int intc,nd,i;FILE *SMSFile;
10383
10384 static int pn[9]={1, 2, 3, 0, 1, 2, 3, -1, 0};
10385 static int dof[9]={2, 2, 2, 2, 2, 2, 1, 1, 1};
10386 static int nsto[9]={0, 0, 0, 0, 0, 0, 0, 0, 0};
10387
10388 static int ndat[9]={0, 0, 0, 0, 0, 0, 0, 0, 0};
10389
10390 static char *nid[]={"D","D","D","D","D","D",
10391 "p","p","p"};
10392 static char *gdcs[]={ "E -Youngs modulus",
10393 "$[Nu]$ -Poissons Ratio",
10394 "ns0s -initial volume fraction solid",
10395 "kL -Darcy parameter",
10396 "$[Gamma]$NM -Newmark Parameter",
10397 "$[Beta]$NM -Newmark Parameter"};
10398
10399 static char *gpcs[]={"p","u1","u2","u3","$[Sigma]$11","$[Sigma]$22",
10400 "$[Sigma]$33","$[Sigma]$12","$[Sigma]$23","$[Sigma]$31","seepage1","seepage2"};
10401 static char *npcs[]={""};
10402 static char *sname[]={""};
10403 static char *idname[]={""};
10404 static int idindex[1];
10405 static char *rdname[]={""};
10406 static char *cswitch[]={""};
10407 static int iswitch[1]={0};
10408 static double dswitch[1]={0e0};
10409 static int rdindex[1];
10410 static int nspecs[9];
10411 static double version[3]={6.818,6.818,11.1};
10412 static double pnweights[9]={1e0,1e0,1e0,0e0,0e0,0e0,
10413 0e0,0e0,0e0};
10414 static double rnodes[27]={1e0,0e0,0e0,0e0,1e0,0e0,
10415 0e0,0e0,0e0,0.5e0,0e0,0e0,
10416 0.5e0,0.5e0,0e0,0e0,0.5e0,0e0,
10417 1e0,0e0,0e0,0e0,1e0,0e0,
10418 0e0,0e0,0e0};
10419 es->ReferenceNodes=rnodes;
10420 if(ng==-1) es->Data= &paraVec[0];
10421 es->id.NoDomainData=6;
10422 es->Code="T2T1_up_nichtlinear_iso_gal_2020_02_05";es->Version=version;
10423 es->MainTitle="";
10424 es->SubTitle="";
10425 es->SubSubTitle="";
10426 es->Bibliography="";
10427 es->id.NoDimensions=2;es->id.NoDOFGlobal=15;es->id.NoDOFCondense=0;es->id.NoNodes=9;
10428 es->id.NoSegmentPoints=8;es->Segments=pn;es->PostNodeWeights=pnweights;
10429 es->id.NoIntSwitch=0;es->IntSwitch=iswitch;es->id.DemoLimitation=0;
10430 es->id.NoDoubleSwitch=0;es->DoubleSwitch=dswitch;
10431 es->id.NoCharSwitch=0;es->CharSwitch=cswitch;
10432 es->DOFGlobal=dof;es->NodeID=nid;es->id.NoGPostData=12;es->id.NoNPostData=0;
10433 es->id.SymmetricTangent=0;es->id.CreateDummyNodes=0;es->id.PostIterationCall=0;es->id.DOFScaling=0;
10434 es->Topology="XX";es->DomainDataNames=gdcs;es->GPostNames=gpcs;es->NPostNames=npcs;
10435 es->AdditionalNodes="{}&";
10436 es->AdditionalGraphics="{}&";
10437 es->MMAInitialisation=MMAInitialisationCode;
10438 es->MMANextStep="";
10439 es->MMAStepBack="";
10440 es->MMAPreIteration="";
10441 es->IDataNames=idname;es->IDataIndex=idindex;es->RDataNames=rdname;es->RDataIndex=rdindex;
10442 es->id.NoIData=0;es->id.NoRData=0;
10443 es->id.ShapeSensitivity=0; es->id.EBCSensitivity=0;es->id.SensitivityOrder=0;
10444 es->id.NoSensNames=0;es->SensitivityNames=sname;es->NodeSpecs=nspecs;
10445// es->user.SPP=SPP;
10446// es->user.SKR=SKR;
10447
10448 es->id.DefaultIntegrationCode=35;
10449 if(ic==-1){intc=35;} else {intc=ic;};
10450 es->id.IntCode=intc;
10451 es->IntPoints = SMTMultiIntPoints(&intc,idata,&es->id.NoIntPoints,
10452 &es->id.NoIntPointsA,&es->id.NoIntPointsB,&es->id.NoIntPointsC,1);
10453
10454 es->id.NoAdditionalData=(int)(0);
10455 es->id.NoTimeStorage=(int)(24);
10456 es->id.NoElementData=(int)(0);
10457
10458 es->NoNodeStorage=nsto;es->NoNodeData=ndat;
10459
10460};
10461
10462/*************************************************************
10463* AceGen 7.114 Linux (9 Jul 20) *
10464* Co. J. Korelc 2020 4 Sep 20 16:26:52 *
10465**************************************************************
10466User : Full professional version
10467Notebook : O2O1_up_lin_el_iso_gal_Newmark_mesh_koeln_1D_Ehlers_2020_09_04
10468Evaluation time : 23 s Mode : Optimal
10469Number of formulae : 521 Method: Automatic
10470Subroutine : SKR size: 7982
10471Subroutine : SPP size: 2615
10472Total size of Mathematica code : 10597 subexpressions
10473Total size of C code : 31924 bytes */
10474//Added 07.09.2020 CH
10475template <class SC, class LO, class GO, class NO>
10476void FE<SC,LO,GO,NO>::SMTSetElSpecBiot3D(ElementSpec *es,int *idata,int ic,int ng, vec_dbl_Type& paraVec)
10477{
10478 int intc,nd,i;FILE *SMSFile;
10479 static int pn[33]={1, 2, 4, 0, 1, 4, 3, 0, 1, 2, 3, 0, 2, 3, 4, 0, 1, 2, 4, -1, 1, 4, 3, -2, 1, 2, 3, -3, 2, 3, 4, -4, 0};
10480 static int dof[14]={3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1};
10481 static int nsto[14]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
10482
10483 static int ndat[14]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
10484
10485 //static int esdat[1]={0}; only used in new release
10486
10487 static char *nid[]={"D","D","D","D","D","D",
10488 "D","D","D","D","p","p",
10489 "p","p"};
10490 static char *gdcs[]={"E -Youngs modulus","$[Nu]$ -Poissons Ratio","bx -body force","by -body force","bz -body force","ns0s -initial volume fraction solid",
10491 "kL -Darcy parameter","$[Rho]$SR -effective density solid","$[Rho]$FR -effective density solid","g -gravity","$[Gamma]$NM -Newmark Parameter","$[Beta]$NM -Newmark Parameter"};
10492 static double defd[]={200e0,0e0,0e0,0e0,0e0,0.67e0,
10493 0.1e-3,2000e0,1000e0,0.9810000000000001e1,0.5e0,0.25e0,
10494 0e0};
10495 static char *gpcs[]={"p","u1","u2","u3","$[Sigma]$11","$[Sigma]$22",
10496 "$[Sigma]$33","$[Sigma]$12","$[Sigma]$23","$[Sigma]$31","seepage1","seepage2",
10497 "seepage3"};
10498 static char *npcs[]={""};
10499 static char *sname[]={""};
10500 static char *idname[]={""};
10501 static int idindex[1];
10502 static char *rdname[]={""};
10503 static char *cswitch[]={""};
10504 static int iswitch[1]={0};
10505 static double dswitch[1]={0e0};
10506 static int rdindex[1];
10507 static int nspecs[14];
10508 static double version[3]={7.114,7.114,11.1};
10509 static double pnweights[14]={1e0,1e0,1e0,1e0,0e0,0e0,
10510 0e0,0e0,0e0,0e0,0e0,0e0,
10511 0e0,0e0};
10512 static double rnodes[42]={1e0,0e0,0e0,0e0,1e0,0e0,
10513 0e0,0e0,1e0,0e0,0e0,0e0,
10514 0.5e0,0.5e0,0e0,0e0,0.5e0,0.5e0,
10515 0.5e0,0e0,0.5e0,0.5e0,0e0,0e0,
10516 0e0,0.5e0,0e0,0e0,0e0,0.5e0,
10517 1e0,0e0,0e0,0e0,1e0,0e0,
10518 0e0,0e0,1e0,0e0,0e0,0e0};
10519 es->ReferenceNodes=rnodes;
10520
10521 if(ng==-1)
10522 es->Data=&paraVec[0];
10523 //es->Data=defd;
10524 es->id.NoDomainData=12;
10525 es->Code="O2O1_up_lin_el_iso_gal_Newmark_mesh_koeln_1D_Ehlers_2020_09_04";es->Version=version;
10526 es->MainTitle="";
10527 es->SubTitle="";
10528 es->SubSubTitle="";
10529 es->Bibliography="";
10530 es->id.NoDimensions=3;es->id.NoDOFGlobal=34;es->id.NoDOFCondense=0;es->id.NoNodes=14;
10531 es->id.NoSegmentPoints=32;es->Segments=pn;es->PostNodeWeights=pnweights;
10532 es->id.NoIntSwitch=0;es->IntSwitch=iswitch;
10533 //es->id.LocalReKe=0; LocalReKe is new and had a different name before (see sms.h(pp)). Was changed with new AceGen/AceFEM release.
10534 es->id.NoDoubleSwitch=0;es->DoubleSwitch=dswitch;
10535 es->id.NoCharSwitch=0;es->id.WorkingVectorSize=1817;es->CharSwitch=cswitch;
10536 es->DOFGlobal=dof;es->NodeID=nid;es->id.NoGPostData=13;es->id.NoNPostData=0;
10537 es->id.SymmetricTangent=0;es->id.PostIterationCall=0;es->id.DOFScaling=0;
10538 es->Topology="XX";es->DomainDataNames=gdcs;es->GPostNames=gpcs;es->NPostNames=npcs;
10539 es->AdditionalNodes="{}&";
10540 es->AdditionalGraphics="{Null,Null,Null}";
10541 es->MMAInitialisation=MMAInitialisationCode;
10542 es->MMANextStep="";
10543 es->MMAStepBack="";
10544 es->MMAPreIteration="";
10545 es->IDataNames=idname;es->IDataIndex=idindex;es->RDataNames=rdname;es->RDataIndex=rdindex;
10546 es->id.NoIData=0;es->id.NoRData=0;
10547 es->id.ShapeSensitivity=0; es->id.EBCSensitivity=0;es->id.SensitivityOrder=0;
10548 es->id.NoSensNames=0;es->SensitivityNames=sname;es->NodeSpecs=nspecs;
10549// es->user.SPP=SPP;
10550// es->user.SKR=SKR;
10551
10552 es->id.DefaultIntegrationCode=40;
10553 if(ic==-1){intc=40;} else {intc=ic;};
10554 es->id.IntCode=intc;
10555 es->IntPoints = SMTMultiIntPoints(&intc,idata,&es->id.NoIntPoints,
10556 &es->id.NoIntPointsA,&es->id.NoIntPointsB,&es->id.NoIntPointsC,1);
10557 es->id.NoAdditionalData=(int)(0);
10558 es->id.NoTimeStorage=(int)(60);
10559 es->id.NoElementData=(int)(0);
10560
10561
10562 es->NoNodeStorage=nsto;es->NoNodeData=ndat;
10563
10564 //es->ExtraSensitivityData=esdat;
10565 //ExtraSensitivityData is new. Was introduced with new AceGen/AceFEM release.
10566};
10567
10568
10569
10570template <class SC, class LO, class GO, class NO>
10571void FE<SC,LO,GO,NO>::SKR_Biot(double* v,ElementSpec *es,ElementData *ed,NodeSpec **ns
10572 ,NodeData **nd,double *rdata,int *idata,double *p,double **s)
10573{
10574 int i107,i109,i215,i230;
10575 v[5162]=0e0;
10576 v[5163]=0e0;
10577 v[5164]=0e0;
10578 v[5165]=0e0;
10579 v[5166]=0e0;
10580 v[5167]=0e0;
10581 v[5168]=0e0;
10582 v[5169]=1e0;
10583 v[5170]=0e0;
10584 v[5171]=-1e0;
10585 v[5172]=0e0;
10586 v[5173]=0e0;
10587 v[5174]=0e0;
10588 v[5175]=0e0;
10589 v[5176]=0e0;
10590 v[5132]=0e0;
10591 v[5133]=0e0;
10592 v[5134]=0e0;
10593 v[5135]=0e0;
10594 v[5136]=0e0;
10595 v[5137]=0e0;
10596 v[5138]=0e0;
10597 v[5139]=1e0;
10598 v[5140]=0e0;
10599 v[5141]=0e0;
10600 v[5142]=0e0;
10601 v[5143]=-1e0;
10602 v[5144]=0e0;
10603 v[5145]=0e0;
10604 v[5146]=0e0;
10605 v[5102]=0e0;
10606 v[5103]=0e0;
10607 v[5104]=0e0;
10608 v[5105]=0e0;
10609 v[5106]=0e0;
10610 v[5107]=0e0;
10611 v[5108]=1e0;
10612 v[5109]=0e0;
10613 v[5110]=-1e0;
10614 v[5111]=0e0;
10615 v[5112]=0e0;
10616 v[5113]=0e0;
10617 v[5114]=0e0;
10618 v[5115]=0e0;
10619 v[5116]=0e0;
10620 v[5072]=0e0;
10621 v[5073]=0e0;
10622 v[5074]=0e0;
10623 v[5075]=0e0;
10624 v[5076]=0e0;
10625 v[5077]=0e0;
10626 v[5078]=1e0;
10627 v[5079]=0e0;
10628 v[5080]=0e0;
10629 v[5081]=0e0;
10630 v[5082]=-1e0;
10631 v[5083]=0e0;
10632 v[5084]=0e0;
10633 v[5085]=0e0;
10634 v[5086]=0e0;
10635 v[5057]=0e0;
10636 v[5058]=0e0;
10637 v[5059]=0e0;
10638 v[5060]=0e0;
10639 v[5061]=0e0;
10640 v[5062]=0e0;
10641 v[5063]=0e0;
10642 v[5064]=0e0;
10643 v[5065]=0e0;
10644 v[5066]=0e0;
10645 v[5067]=0e0;
10646 v[5068]=0e0;
10647 v[5069]=1e0;
10648 v[5070]=0e0;
10649 v[5071]=-1e0;
10650 v[5042]=0e0;
10651 v[5043]=0e0;
10652 v[5044]=0e0;
10653 v[5045]=0e0;
10654 v[5046]=0e0;
10655 v[5047]=0e0;
10656 v[5048]=0e0;
10657 v[5049]=0e0;
10658 v[5050]=0e0;
10659 v[5051]=0e0;
10660 v[5052]=0e0;
10661 v[5053]=0e0;
10662 v[5054]=0e0;
10663 v[5055]=1e0;
10664 v[5056]=-1e0;
10665
10666 //es->Data sind Materialparameter
10667 v[191]=es->Data[5];
10668 v[194]=es->Data[4]/(2e0*(1e0+v[191]));
10669 v[192]=(2e0*v[191]*v[194])/(1e0-2e0*v[191]);
10670 v[186]=es->Data[3];
10671 v[183]=es->Data[2];
10672 // nd sind Nodalwerte, Anzahl an structs in nd sollte den Knoten entsprechen, bei P2-P1 in 2D also 9
10673 // In X stehen die Koordinaten, X[0] ist x-Koordinate, X[1] ist y-Koordinate, etc.
10674 v[1]=nd[0]->X[0];
10675 v[2]=nd[0]->X[1];
10676 v[3]=nd[1]->X[0];
10677 v[4]=nd[1]->X[1];
10678 v[5]=nd[2]->X[0];
10679 v[6]=nd[2]->X[1];
10680 v[7]=nd[3]->X[0];
10681 v[8]=nd[3]->X[1];
10682 v[9]=nd[4]->X[0];
10683 v[10]=nd[4]->X[1];
10684 v[11]=nd[5]->X[0];
10685 v[12]=nd[5]->X[1];
10686 // at ist die Loesung im letzten Newtonschritt.
10687 v[19]=nd[0]->at[0];
10688 v[20]=nd[0]->at[1];
10689 v[21]=nd[1]->at[0];
10690 v[22]=nd[1]->at[1];
10691 v[23]=nd[2]->at[0];
10692 v[24]=nd[2]->at[1];
10693 v[25]=nd[3]->at[0];
10694 v[26]=nd[3]->at[1];
10695 v[27]=nd[4]->at[0];
10696 v[28]=nd[4]->at[1];
10697 v[29]=nd[5]->at[0];
10698 v[30]=nd[5]->at[1];
10699 v[31]=nd[6]->at[0];
10700 v[32]=nd[7]->at[0];
10701 v[33]=nd[8]->at[0];
10702 v[172]=v[32]-v[33];
10703 v[171]=v[31]-v[33];
10704 // ap ist die Loesung im letzten Zeitschritt.
10705 v[490]=-nd[0]->ap[0]+v[19];
10706 v[497]=-nd[0]->ap[1]+v[20];
10707 v[492]=-nd[1]->ap[0]+v[21];
10708 v[498]=-nd[1]->ap[1]+v[22];
10709 v[493]=-nd[2]->ap[0]+v[23];
10710 v[499]=-nd[2]->ap[1]+v[24];
10711 v[494]=-nd[3]->ap[0]+v[25];
10712 v[500]=-nd[3]->ap[1]+v[26];
10713 v[495]=-nd[4]->ap[0]+v[27];
10714 v[501]=-nd[4]->ap[1]+v[28];
10715 v[496]=-nd[5]->ap[0]+v[29];
10716 v[488]=-nd[5]->ap[1]+v[30];
10717 //rdata ist die Zeitschrittweite, RD_TimeIncrement wird in sms.h definiert, entsprechend wird auch die Laenge von rdata dort definiert. Standard 400, aber auch nicht gesetzt. Wert muss selber initialisiert werden; eventuell kuerzer moeglich.
10718 v[49]=rdata[RD_TimeIncrement];
10719 //hp:history previous (timestep); previous solution
10720 v[50]=ed->hp[0];
10721 v[51]=ed->hp[1];
10722 v[52]=ed->hp[2];
10723 v[53]=ed->hp[3];
10724 v[54]=ed->hp[4];
10725 v[55]=ed->hp[5];
10726 v[56]=ed->hp[6];
10727 v[57]=ed->hp[7];
10728 v[58]=ed->hp[8];
10729 v[59]=ed->hp[9];
10730 v[60]=ed->hp[10];
10731 v[61]=ed->hp[11];
10732 v[62]=ed->hp[12];
10733 v[63]=ed->hp[13];
10734 v[64]=ed->hp[14];
10735 v[65]=ed->hp[15];
10736 v[66]=ed->hp[16];
10737 v[67]=ed->hp[17];
10738 v[68]=ed->hp[18];
10739 v[69]=ed->hp[19];
10740 v[70]=ed->hp[20];
10741 v[71]=ed->hp[21];
10742 v[72]=ed->hp[22];
10743 v[73]=ed->hp[23];
10744 v[75]=es->Data[1];
10745 v[489]=1e0/(Power(v[49],2)*v[75]);
10746 v[491]=-((v[49]*v[49])*(0.5e0-v[75]));
10747 v[79]=es->Data[0]/(v[49]*v[75]);
10748 v[486]=-(v[49]*v[79]);
10749 v[487]=(1e0+v[486]/2e0)*v[49];
10750 v[77]=1e0+v[486];
10751 v[76]=v[487]*v[62]+v[50]*v[77]+v[490]*v[79];
10752 v[80]=v[487]*v[68]+v[56]*v[77]+v[497]*v[79];
10753 v[81]=v[487]*v[63]+v[51]*v[77]+v[492]*v[79];
10754 v[82]=v[487]*v[69]+v[57]*v[77]+v[498]*v[79];
10755 v[83]=v[487]*v[64]+v[52]*v[77]+v[493]*v[79];
10756 v[84]=v[487]*v[70]+v[58]*v[77]+v[499]*v[79];
10757 v[85]=v[487]*v[65]+v[53]*v[77]+v[494]*v[79];
10758 v[86]=v[487]*v[71]+v[59]*v[77]+v[500]*v[79];
10759 v[87]=v[487]*v[66]+v[54]*v[77]+v[495]*v[79];
10760 v[88]=v[487]*v[72]+v[60]*v[77]+v[501]*v[79];
10761 v[89]=v[487]*v[67]+v[55]*v[77]+v[496]*v[79];
10762 v[90]=v[487]*v[73]+v[61]*v[77]+v[488]*v[79];
10763
10764 ed->ht[0]=v[76];
10765 ed->ht[1]=v[81];
10766 ed->ht[2]=v[83];
10767 ed->ht[3]=v[85];
10768 ed->ht[4]=v[87];
10769 ed->ht[5]=v[89];
10770 ed->ht[6]=v[80];
10771 ed->ht[7]=v[82];
10772 ed->ht[8]=v[84];
10773 ed->ht[9]=v[86];
10774 ed->ht[10]=v[88];
10775 ed->ht[11]=v[90];
10776 ed->ht[12]=v[489]*(v[490]-v[49]*v[50]+v[491]*v[62]);
10777 ed->ht[13]=v[489]*(v[492]-v[49]*v[51]+v[491]*v[63]);
10778 ed->ht[14]=v[489]*(v[493]-v[49]*v[52]+v[491]*v[64]);
10779 ed->ht[15]=v[489]*(v[494]-v[49]*v[53]+v[491]*v[65]);
10780 ed->ht[16]=v[489]*(v[495]-v[49]*v[54]+v[491]*v[66]);
10781 ed->ht[17]=v[489]*(v[496]-v[49]*v[55]+v[491]*v[67]);
10782 ed->ht[18]=v[489]*(v[497]-v[49]*v[56]+v[491]*v[68]);
10783 ed->ht[19]=v[489]*(v[498]-v[49]*v[57]+v[491]*v[69]);
10784 ed->ht[20]=v[489]*(v[499]-v[49]*v[58]+v[491]*v[70]);
10785 ed->ht[21]=v[489]*(v[500]-v[49]*v[59]+v[491]*v[71]);
10786 ed->ht[22]=v[489]*(v[501]-v[49]*v[60]+v[491]*v[72]);
10787 ed->ht[23]=v[489]*(v[488]-v[49]*v[61]+v[491]*v[73]);
10788 //es->id.NoIntPoints wird in SMTSetElSpec gesetzt
10789 for(i107=1;i107<=es->id.NoIntPoints;i107++){
10790 i109=4*(-1+i107);
10791 v[108]=es->IntPoints[i109];
10792 v[137]=4e0*v[108];
10793 v[132]=-1e0+v[137];
10794 v[110]=es->IntPoints[1+i109];
10795 v[136]=4e0*v[110];
10796 v[133]=-1e0+v[136];
10797 v[119]=-1e0+v[108]+v[110];
10798 v[5192]=0e0;
10799 v[5193]=0e0;
10800 v[5194]=0e0;
10801 v[5195]=0e0;
10802 v[5196]=0e0;
10803 v[5197]=0e0;
10804 v[5198]=0e0;
10805 v[5199]=0e0;
10806 v[5200]=0e0;
10807 v[5201]=0e0;
10808 v[5202]=0e0;
10809 v[5203]=0e0;
10810 v[5204]=-v[108];
10811 v[5205]=-v[110];
10812 v[5206]=v[119];
10813 v[139]=-4e0*v[119];
10814 v[140]=-v[137]+v[139];
10815 v[138]=-v[136]+v[139];
10816 v[135]=-1e0+2e0*v[108]+2e0*v[110]+2e0*v[119];
10817 v[5177]=0e0;
10818 v[5178]=v[132];
10819 v[5179]=0e0;
10820 v[5180]=0e0;
10821 v[5181]=0e0;
10822 v[5182]=v[135];
10823 v[5183]=0e0;
10824 v[5184]=0e0;
10825 v[5185]=0e0;
10826 v[5186]=0e0;
10827 v[5187]=0e0;
10828 v[5188]=v[140];
10829 v[5189]=0e0;
10830 v[5190]=0e0;
10831 v[5191]=0e0;
10832 v[5147]=0e0;
10833 v[5148]=0e0;
10834 v[5149]=0e0;
10835 v[5150]=v[133];
10836 v[5151]=0e0;
10837 v[5152]=v[135];
10838 v[5153]=0e0;
10839 v[5154]=0e0;
10840 v[5155]=0e0;
10841 v[5156]=v[138];
10842 v[5157]=0e0;
10843 v[5158]=0e0;
10844 v[5159]=0e0;
10845 v[5160]=0e0;
10846 v[5161]=0e0;
10847 v[5117]=v[132];
10848 v[5118]=0e0;
10849 v[5119]=0e0;
10850 v[5120]=0e0;
10851 v[5121]=v[135];
10852 v[5122]=0e0;
10853 v[5123]=0e0;
10854 v[5124]=0e0;
10855 v[5125]=0e0;
10856 v[5126]=0e0;
10857 v[5127]=v[140];
10858 v[5128]=0e0;
10859 v[5129]=0e0;
10860 v[5130]=0e0;
10861 v[5131]=0e0;
10862 v[5087]=0e0;
10863 v[5088]=0e0;
10864 v[5089]=v[133];
10865 v[5090]=0e0;
10866 v[5091]=v[135];
10867 v[5092]=0e0;
10868 v[5093]=0e0;
10869 v[5094]=0e0;
10870 v[5095]=v[138];
10871 v[5096]=0e0;
10872 v[5097]=0e0;
10873 v[5098]=0e0;
10874 v[5099]=0e0;
10875 v[5100]=0e0;
10876 v[5101]=0e0;
10877 v[164]=v[135]*v[84];
10878 v[161]=v[135]*v[83];
10879 v[153]=v[135]*v[24];
10880 v[154]=v[153]+v[133]*v[22]+v[138]*v[28]+v[137]*(v[26]-v[30]);
10881 v[152]=v[153]+v[132]*v[20]+v[136]*(v[26]-v[28])+v[140]*v[30];
10882 v[150]=v[135]*v[23];
10883 v[151]=v[150]+v[133]*v[21]+v[138]*v[27]+v[137]*(v[25]-v[29]);
10884 v[149]=v[150]+v[132]*v[19]+v[136]*(v[25]-v[27])+v[140]*v[29];
10885 v[145]=v[135]*v[6];
10886 v[146]=v[10]*v[138]+v[145]+v[133]*v[4]+v[137]*(-v[12]+v[8]);
10887 v[144]=v[12]*v[140]+v[145]+v[132]*v[2]+v[136]*(-v[10]+v[8]);
10888 v[142]=v[135]*v[5];
10889 v[143]=v[142]+v[133]*v[3]+v[137]*(-v[11]+v[7])+v[138]*v[9];
10890 v[141]=v[1]*v[132]+v[11]*v[140]+v[142]+v[136]*(v[7]-v[9]);
10891 v[155]=-(v[143]*v[144])+v[141]*v[146];
10892 v[525]=-(v[143]/v[155]);
10893 v[529]=v[140]*v[525];
10894 v[524]=v[141]/v[155];
10895 v[527]=v[138]*v[524];
10896 v[523]=v[146]/v[155];
10897 v[528]=v[140]*v[523];
10898 v[522]=-(v[144]/v[155]);
10899 v[526]=v[138]*v[522];
10900 v[519]=1e0/Power(v[155],2);
10901 v[503]=v[137]/v[155];
10902 v[502]=v[136]/v[155];
10903 v[267]=v[143]*v[502];
10904 v[266]=v[141]*v[503];
10905 v[263]=v[146]*v[502];
10906 v[262]=v[144]*v[503];
10907 v[148]=es->IntPoints[3+i109]*std::fabs(v[155]);
10908 v[176]=(v[146]*v[149]-v[144]*v[151])/v[155];
10909 v[179]=(-(v[143]*v[152])+v[141]*v[154])/v[155];
10910 v[195]=v[176]+v[179];
10911 v[505]=v[192]*v[195]-v[108]*v[31]-v[110]*v[32]+v[119]*v[33];
10912 v[185]=1e0-v[183]*(1e0+v[195]);
10913 v[504]=v[186]/(v[155]*v[185]);
10914 v[510]=v[185]*v[504];
10915 v[198]=-(((v[143]*v[149]-v[141]*v[151]-v[146]*v[152]+v[144]*v[154])*v[194])/v[155]);
10916 v[204]=2e0*v[176]*v[194]+v[505];
10917 v[205]=2e0*v[179]*v[194]+v[505];
10918 v[208]=(-(v[144]*(v[161]+v[133]*v[81]+v[137]*v[85]+v[138]*v[87]-v[137]*v[89]))+v[146]*(v[161]
10919 +v[132]*v[76]+v[136]*v[85]-v[136]*v[87]+v[140]*v[89])+v[141]*(v[164]+v[133]*v[82]+v[137]*v[86]
10920 +v[138]*v[88]-v[137]*v[90])-v[143]*(v[164]+v[132]*v[80]+v[136]*v[86]-v[136]*v[88]+v[140]*v[90]))
10921 /v[155];
10922 v[210]=(-(v[146]*v[171])+v[144]*v[172])*v[185]*v[504];
10923 v[211]=(v[143]*v[171]-v[141]*v[172])*v[185]*v[504];
10924 v[217]=(v[146]*v[198]-v[143]*v[205])/v[155];
10925 v[225]=v[136]*v[217];
10926 v[218]=(-(v[144]*v[198])+v[141]*v[205])/v[155];
10927 v[226]=v[137]*v[218];
10928 v[219]=(-(v[143]*v[198])+v[146]*v[204])/v[155];
10929 v[223]=v[136]*v[219];
10930 v[220]=(v[141]*v[198]-v[144]*v[204])/v[155];
10931 v[224]=v[137]*v[220];
10932 v[221]=(v[146]*v[210]-v[143]*v[211])/v[155];
10933 v[222]=(-(v[144]*v[210])+v[141]*v[211])/v[155];
10934 v[5023]=v[132]*v[219];
10935 v[5024]=v[132]*v[217];
10936 v[5025]=v[133]*v[220];
10937 v[5026]=v[133]*v[218];
10938 v[5027]=v[135]*(v[219]+v[220]);
10939 v[5028]=v[135]*(v[217]+v[218]);
10940 v[5029]=v[223]+v[224];
10941 v[5030]=v[225]+v[226];
10942 v[5031]=v[138]*v[220]-v[223];
10943 v[5032]=v[138]*v[218]-v[225];
10944 v[5033]=v[140]*v[219]-v[224];
10945 v[5034]=v[140]*v[217]-v[226];
10946 v[5035]=-(v[108]*v[208])+v[221];
10947 v[5036]=-(v[110]*v[208])+v[222];
10948 v[5037]=v[119]*v[208]-v[221]-v[222];
10949// for(i215=1;i215<=15;i215++){
10950//
10951// for(i230=1;i230<=15;i230++){
10952// std::cout << " pre s[i215-1][i230-1]:"<< s[i215-1][i230-1] << std::endl;
10953// }
10954//
10955// }
10956
10957 for(i215=1;i215<=15;i215++){
10958 v[233]=v[5041+i215];
10959 v[234]=v[5056+i215];
10960 v[509]=v[5191+i215]*v[79];
10961 v[261]=v[135]*v[509];
10962 v[260]=v[509]/v[155];
10963 v[246]=((v[141]*v[233]-v[143]*v[234])*v[510])/v[155];
10964 v[247]=((-(v[144]*v[233])+v[146]*v[234])*v[510])/v[155];
10965 v[238]=v[137]*v[5071+i215]+v[5086+i215];
10966 v[239]=v[136]*v[5101+i215]+v[5116+i215];
10967 v[240]=(-(v[144]*v[238])+v[146]*v[239])/v[155];
10968 v[241]=v[137]*v[5131+i215]+v[5146+i215];
10969 v[242]=v[136]*v[5161+i215]+v[5176+i215];
10970 v[243]=(v[141]*v[241]-v[143]*v[242])/v[155];
10971
10972 v[256]=v[194]*(v[141]*v[238]-v[143]*v[239]-v[144]*v[241]+v[146]*v[242])*v[519];
10973 v[245]=v[143]*v[246]-v[146]*v[247];
10974 v[248]=-(v[141]*v[246])+v[144]*v[247];
10975 v[249]=-v[240]-v[243];
10976 v[252]=-(v[192]*v[249]);
10977 v[520]=(2e0*v[194]*v[243]+v[252])/v[155];
10978 v[521]=(2e0*v[194]*v[240]+v[252])/v[155];
10979 v[255]=v[146]*v[256]-v[143]*v[520];
10980 v[268]=v[136]*v[255];
10981 v[257]=-(v[144]*v[256])+v[141]*v[520];
10982 v[269]=v[137]*v[257];
10983 v[258]=-(v[143]*v[256])+v[146]*v[521];
10984 v[264]=v[136]*v[258];
10985 v[259]=v[141]*v[256]-v[144]*v[521];
10986 v[265]=v[137]*v[259];
10987
10988 v[5207]=v[132]*(v[258]+v[146]*v[260]);
10989 v[5208]=v[132]*(v[255]-v[143]*v[260]);
10990
10991 v[5209]=v[133]*(v[259]-v[144]*v[260]);
10992 v[5210]=v[133]*(v[257]+v[141]*v[260]);
10993 v[5211]=v[135]*(v[258]+v[259])+v[261]*(v[522]+v[523]);
10994 v[5212]=v[135]*(v[255]+v[257])+v[261]*(v[524]+v[525]);
10995 v[5213]=v[264]+v[265]+(-v[262]+v[263])*v[509];
10996 v[5214]=v[268]+v[269]+(v[266]-v[267])*v[509];
10997 v[5215]=v[138]*v[259]-v[264]+v[509]*(-v[263]+v[526]);
10998 v[5216]=v[138]*v[257]-v[268]+v[509]*(v[267]+v[527]);
10999 v[5217]=v[140]*v[258]-v[265]+v[509]*(v[262]+v[528]);
11000 v[5218]=v[140]*v[255]-v[269]+v[509]*(-v[266]+v[529]);
11001 v[5219]=v[245]+v[108]*v[249];
11002 v[5220]=v[248]+v[110]*v[249];
11003 v[5221]=-v[245]-v[248]-v[119]*v[249];
11004 p[i215-1]+=v[148]*v[5022+i215];
11005 for(i230=1;i230<=15;i230++){
11006 s[i215-1][i230-1]+=v[148]*v[5206+i230];
11007
11008 };/* end for */
11009 };/* end for */
11010 };/* end for */
11011};
11012
11013template <class SC, class LO, class GO, class NO>
11014void FE<SC,LO,GO,NO>::SKR_Biot_StVK(double* v,ElementSpec *es,ElementData *ed,NodeSpec **ns
11015 ,NodeData **nd,double *rdata,int *idata,double *p,double **s)
11016{
11017 int i114,i116,i233,i250,b297;
11018 FILE *SMSFile;
11019 v[5132]=0e0;
11020 v[5133]=0e0;
11021 v[5134]=0e0;
11022 v[5135]=0e0;
11023 v[5136]=0e0;
11024 v[5137]=0e0;
11025 v[5138]=0e0;
11026 v[5139]=1e0;
11027 v[5140]=0e0;
11028 v[5141]=-1e0;
11029 v[5142]=0e0;
11030 v[5143]=0e0;
11031 v[5144]=0e0;
11032 v[5145]=0e0;
11033 v[5146]=0e0;
11034 v[5102]=0e0;
11035 v[5103]=0e0;
11036 v[5104]=0e0;
11037 v[5105]=0e0;
11038 v[5106]=0e0;
11039 v[5107]=0e0;
11040 v[5108]=0e0;
11041 v[5109]=1e0;
11042 v[5110]=0e0;
11043 v[5111]=0e0;
11044 v[5112]=0e0;
11045 v[5113]=-1e0;
11046 v[5114]=0e0;
11047 v[5115]=0e0;
11048 v[5116]=0e0;
11049 v[5072]=0e0;
11050 v[5073]=0e0;
11051 v[5074]=0e0;
11052 v[5075]=0e0;
11053 v[5076]=0e0;
11054 v[5077]=0e0;
11055 v[5078]=1e0;
11056 v[5079]=0e0;
11057 v[5080]=-1e0;
11058 v[5081]=0e0;
11059 v[5082]=0e0;
11060 v[5083]=0e0;
11061 v[5084]=0e0;
11062 v[5085]=0e0;
11063 v[5086]=0e0;
11064 v[5042]=0e0;
11065 v[5043]=0e0;
11066 v[5044]=0e0;
11067 v[5045]=0e0;
11068 v[5046]=0e0;
11069 v[5047]=0e0;
11070 v[5048]=1e0;
11071 v[5049]=0e0;
11072 v[5050]=0e0;
11073 v[5051]=0e0;
11074 v[5052]=-1e0;
11075 v[5053]=0e0;
11076 v[5054]=0e0;
11077 v[5055]=0e0;
11078 v[5056]=0e0;
11079 v[5177]=0e0;
11080 v[5178]=0e0;
11081 v[5179]=0e0;
11082 v[5180]=0e0;
11083 v[5181]=0e0;
11084 v[5182]=0e0;
11085 v[5183]=0e0;
11086 v[5184]=0e0;
11087 v[5185]=0e0;
11088 v[5186]=0e0;
11089 v[5187]=0e0;
11090 v[5188]=0e0;
11091 v[5189]=1e0;
11092 v[5190]=0e0;
11093 v[5191]=-1e0;
11094 v[5162]=0e0;
11095 v[5163]=0e0;
11096 v[5164]=0e0;
11097 v[5165]=0e0;
11098 v[5166]=0e0;
11099 v[5167]=0e0;
11100 v[5168]=0e0;
11101 v[5169]=0e0;
11102 v[5170]=0e0;
11103 v[5171]=0e0;
11104 v[5172]=0e0;
11105 v[5173]=0e0;
11106 v[5174]=0e0;
11107 v[5175]=1e0;
11108 v[5176]=-1e0;
11109 v[1]=nd[0]->X[0];
11110 v[2]=nd[0]->X[1];
11111 v[3]=nd[1]->X[0];
11112 v[4]=nd[1]->X[1];
11113 v[5]=nd[2]->X[0];
11114 v[6]=nd[2]->X[1];
11115 v[7]=nd[3]->X[0];
11116 v[8]=nd[3]->X[1];
11117 v[9]=nd[4]->X[0];
11118 v[10]=nd[4]->X[1];
11119 v[11]=nd[5]->X[0];
11120 v[12]=nd[5]->X[1];
11121 v[19]=nd[0]->at[0];
11122 v[20]=nd[0]->at[1];
11123 v[21]=nd[1]->at[0];
11124 v[22]=nd[1]->at[1];
11125 v[23]=nd[2]->at[0];
11126 v[24]=nd[2]->at[1];
11127 v[25]=nd[3]->at[0];
11128 v[26]=nd[3]->at[1];
11129 v[27]=nd[4]->at[0];
11130 v[28]=nd[4]->at[1];
11131 v[29]=nd[5]->at[0];
11132 v[30]=nd[5]->at[1];
11133 v[31]=nd[6]->at[0];
11134 v[32]=nd[7]->at[0];
11135 v[33]=nd[8]->at[0];
11136 v[179]=v[32]-v[33];
11137 v[178]=v[31]-v[33];
11138 v[34]=nd[0]->ap[0];
11139 v[574]=v[19]-v[34];
11140 v[35]=nd[0]->ap[1];
11141 v[576]=v[20]-v[35];
11142 v[36]=nd[1]->ap[0];
11143 v[578]=v[21]-v[36];
11144 v[37]=nd[1]->ap[1];
11145 v[579]=v[22]-v[37];
11146 v[38]=nd[2]->ap[0];
11147 v[580]=v[23]-v[38];
11148 v[39]=nd[2]->ap[1];
11149 v[581]=v[24]-v[39];
11150 v[40]=nd[3]->ap[0];
11151 v[582]=v[25]-v[40];
11152 v[41]=nd[3]->ap[1];
11153 v[583]=v[26]-v[41];
11154 v[42]=nd[4]->ap[0];
11155 v[584]=v[27]-v[42];
11156 v[43]=nd[4]->ap[1];
11157 v[585]=v[28]-v[43];
11158 v[44]=nd[5]->ap[0];
11159 v[586]=v[29]-v[44];
11160 v[45]=nd[5]->ap[1];
11161 v[587]=v[30]-v[45];
11162 v[49]=es->Data[0];
11163 v[50]=es->Data[1];
11164 v[571]=v[49]/(1e0+v[50]);
11165 v[51]=(v[50]*v[571])/(1e0-2e0*v[50]);
11166 v[53]=v[571]/2e0;
11167 v[54]=es->Data[2];
11168 v[55]=es->Data[3];
11169 v[56]=rdata[RD_TimeIncrement];
11170 v[57]=ed->hp[0];
11171 v[58]=ed->hp[1];
11172 v[59]=ed->hp[2];
11173 v[60]=ed->hp[3];
11174 v[61]=ed->hp[4];
11175 v[62]=ed->hp[5];
11176 v[63]=ed->hp[6];
11177 v[64]=ed->hp[7];
11178 v[65]=ed->hp[8];
11179 v[66]=ed->hp[9];
11180 v[67]=ed->hp[10];
11181 v[68]=ed->hp[11];
11182 v[69]=ed->hp[12];
11183 v[70]=ed->hp[13];
11184 v[71]=ed->hp[14];
11185 v[72]=ed->hp[15];
11186 v[73]=ed->hp[16];
11187 v[74]=ed->hp[17];
11188 v[75]=ed->hp[18];
11189 v[76]=ed->hp[19];
11190 v[77]=ed->hp[20];
11191 v[78]=ed->hp[21];
11192 v[79]=ed->hp[22];
11193 v[80]=ed->hp[23];
11194 v[82]=es->Data[5];
11195 v[575]=1e0/(Power(v[56],2)*v[82]);
11196 v[577]=-((v[56]*v[56])*(0.5e0-v[82]));
11197 v[86]=es->Data[4]/(v[56]*v[82]);
11198 v[572]=-(v[56]*v[86]);
11199 v[573]=v[56]*(1e0+v[572]/2e0);
11200 v[84]=1e0+v[572];
11201 v[83]=v[573]*v[69]+v[57]*v[84]+v[574]*v[86];
11202 v[87]=v[573]*v[75]+v[63]*v[84]+v[576]*v[86];
11203 v[88]=v[573]*v[70]+v[58]*v[84]+v[578]*v[86];
11204 v[89]=v[573]*v[76]+v[64]*v[84]+v[579]*v[86];
11205 v[90]=v[573]*v[71]+v[59]*v[84]+v[580]*v[86];
11206 v[91]=v[573]*v[77]+v[65]*v[84]+v[581]*v[86];
11207 v[92]=v[573]*v[72]+v[60]*v[84]+v[582]*v[86];
11208 v[93]=v[573]*v[78]+v[66]*v[84]+v[583]*v[86];
11209 v[94]=v[573]*v[73]+v[61]*v[84]+v[584]*v[86];
11210 v[95]=v[573]*v[79]+v[67]*v[84]+v[585]*v[86];
11211 v[96]=v[573]*v[74]+v[62]*v[84]+v[586]*v[86];
11212 v[97]=v[573]*v[80]+v[68]*v[84]+v[587]*v[86];
11213 v[98]=v[575]*(-(v[56]*v[57])+v[574]+v[577]*v[69]);
11214 v[102]=v[575]*(v[576]-v[56]*v[63]+v[577]*v[75]);
11215 v[103]=v[575]*(v[578]-v[56]*v[58]+v[577]*v[70]);
11216 v[104]=v[575]*(v[579]-v[56]*v[64]+v[577]*v[76]);
11217 v[105]=v[575]*(v[580]-v[56]*v[59]+v[577]*v[71]);
11218 v[106]=v[575]*(v[581]-v[56]*v[65]+v[577]*v[77]);
11219 v[107]=v[575]*(v[582]-v[56]*v[60]+v[577]*v[72]);
11220 v[108]=v[575]*(v[583]-v[56]*v[66]+v[577]*v[78]);
11221 v[109]=v[575]*(v[584]-v[56]*v[61]+v[577]*v[73]);
11222 v[110]=v[575]*(v[585]-v[56]*v[67]+v[577]*v[79]);
11223 v[111]=v[575]*(v[586]-v[56]*v[62]+v[577]*v[74]);
11224 v[112]=v[575]*(v[587]-v[56]*v[68]+v[577]*v[80]);
11225 ed->ht[0]=v[83];
11226 ed->ht[1]=v[88];
11227 ed->ht[2]=v[90];
11228 ed->ht[3]=v[92];
11229 ed->ht[4]=v[94];
11230 ed->ht[5]=v[96];
11231 ed->ht[6]=v[87];
11232 ed->ht[7]=v[89];
11233 ed->ht[8]=v[91];
11234 ed->ht[9]=v[93];
11235 ed->ht[10]=v[95];
11236 ed->ht[11]=v[97];
11237 ed->ht[12]=v[98];
11238 ed->ht[13]=v[103];
11239 ed->ht[14]=v[105];
11240 ed->ht[15]=v[107];
11241 ed->ht[16]=v[109];
11242 ed->ht[17]=v[111];
11243 ed->ht[18]=v[102];
11244 ed->ht[19]=v[104];
11245 ed->ht[20]=v[106];
11246 ed->ht[21]=v[108];
11247 ed->ht[22]=v[110];
11248 ed->ht[23]=v[112];
11249 for(i114=1;i114<=es->id.NoIntPoints;i114++){
11250 i116=4*(-1+i114);
11251 v[115]=es->IntPoints[i116];
11252 v[144]=4e0*v[115];
11253 v[139]=-1e0+v[144];
11254 v[117]=es->IntPoints[1+i116];
11255 v[143]=4e0*v[117];
11256 v[140]=-1e0+v[143];
11257 v[126]=-1e0+v[115]+v[117];
11258 v[5192]=0e0;
11259 v[5193]=0e0;
11260 v[5194]=0e0;
11261 v[5195]=0e0;
11262 v[5196]=0e0;
11263 v[5197]=0e0;
11264 v[5198]=0e0;
11265 v[5199]=0e0;
11266 v[5200]=0e0;
11267 v[5201]=0e0;
11268 v[5202]=0e0;
11269 v[5203]=0e0;
11270 v[5204]=-v[115];
11271 v[5205]=-v[117];
11272 v[5206]=v[126];
11273 v[146]=-4e0*v[126];
11274 v[147]=-v[144]+v[146];
11275 v[145]=-v[143]+v[146];
11276 v[142]=-1e0+2e0*v[115]+2e0*v[117]+2e0*v[126];
11277 v[5147]=0e0;
11278 v[5148]=v[139];
11279 v[5149]=0e0;
11280 v[5150]=0e0;
11281 v[5151]=0e0;
11282 v[5152]=v[142];
11283 v[5153]=0e0;
11284 v[5154]=0e0;
11285 v[5155]=0e0;
11286 v[5156]=0e0;
11287 v[5157]=0e0;
11288 v[5158]=v[147];
11289 v[5159]=0e0;
11290 v[5160]=0e0;
11291 v[5161]=0e0;
11292 v[5117]=0e0;
11293 v[5118]=0e0;
11294 v[5119]=0e0;
11295 v[5120]=v[140];
11296 v[5121]=0e0;
11297 v[5122]=v[142];
11298 v[5123]=0e0;
11299 v[5124]=0e0;
11300 v[5125]=0e0;
11301 v[5126]=v[145];
11302 v[5127]=0e0;
11303 v[5128]=0e0;
11304 v[5129]=0e0;
11305 v[5130]=0e0;
11306 v[5131]=0e0;
11307 v[5087]=v[139];
11308 v[5088]=0e0;
11309 v[5089]=0e0;
11310 v[5090]=0e0;
11311 v[5091]=v[142];
11312 v[5092]=0e0;
11313 v[5093]=0e0;
11314 v[5094]=0e0;
11315 v[5095]=0e0;
11316 v[5096]=0e0;
11317 v[5097]=v[147];
11318 v[5098]=0e0;
11319 v[5099]=0e0;
11320 v[5100]=0e0;
11321 v[5101]=0e0;
11322 v[5057]=0e0;
11323 v[5058]=0e0;
11324 v[5059]=v[140];
11325 v[5060]=0e0;
11326 v[5061]=v[142];
11327 v[5062]=0e0;
11328 v[5063]=0e0;
11329 v[5064]=0e0;
11330 v[5065]=v[145];
11331 v[5066]=0e0;
11332 v[5067]=0e0;
11333 v[5068]=0e0;
11334 v[5069]=0e0;
11335 v[5070]=0e0;
11336 v[5071]=0e0;
11337 v[171]=v[142]*v[91];
11338 v[168]=v[142]*v[90];
11339 v[160]=v[142]*v[24];
11340 v[161]=v[160]+v[140]*v[22]+v[145]*v[28]+v[144]*(v[26]-v[30]);
11341 v[159]=v[160]+v[139]*v[20]+v[143]*(v[26]-v[28])+v[147]*v[30];
11342 v[157]=v[142]*v[23];
11343 v[158]=v[157]+v[140]*v[21]+v[145]*v[27]+v[144]*(v[25]-v[29]);
11344 v[156]=v[157]+v[139]*v[19]+v[143]*(v[25]-v[27])+v[147]*v[29];
11345 v[152]=v[142]*v[6];
11346 v[153]=v[10]*v[145]+v[152]+v[140]*v[4]+v[144]*(-v[12]+v[8]);
11347 v[151]=v[12]*v[147]+v[152]+v[139]*v[2]+v[143]*(-v[10]+v[8]);
11348 v[149]=v[142]*v[5];
11349 v[150]=v[149]+v[140]*v[3]+v[144]*(-v[11]+v[7])+v[145]*v[9];
11350 v[148]=v[1]*v[139]+v[11]*v[147]+v[149]+v[143]*(v[7]-v[9]);
11351 v[162]=-(v[150]*v[151])+v[148]*v[153];
11352 v[610]=-(v[150]/v[162]);
11353 v[614]=v[147]*v[610];
11354 v[609]=v[148]/v[162];
11355 v[612]=v[145]*v[609];
11356 v[608]=v[153]/v[162];
11357 v[613]=v[147]*v[608];
11358 v[607]=-(v[151]/v[162]);
11359 v[611]=v[145]*v[607];
11360 v[589]=v[144]/v[162];
11361 v[588]=v[143]/v[162];
11362 v[292]=v[150]*v[588];
11363 v[291]=v[148]*v[589];
11364 v[288]=v[153]*v[588];
11365 v[287]=v[151]*v[589];
11366 v[155]=es->IntPoints[3+i116]*std::fabs(v[162]);
11367 v[163]=(v[153]*v[156]-v[151]*v[158])/v[162];
11368 v[164]=(-(v[150]*v[156])+v[148]*v[158])/v[162];
11369 v[165]=(v[153]*v[159]-v[151]*v[161])/v[162];
11370 v[166]=(-(v[150]*v[159])+v[148]*v[161])/v[162];
11371 v[190]=1e0-v[163];
11372 v[191]=1e0-v[166];
11373 v[195]=0.5e0*(-1e0+(v[165]*v[165])+(v[190]*v[190]));
11374 v[200]=0.5e0*(-1e0+(v[164]*v[164])+(v[191]*v[191]));
11375 v[591]=-(v[115]*v[31])-v[117]*v[32]+v[126]*v[33]+(v[195]+v[200])*v[51];
11376 v[206]=1e0-(1e0+v[163]+v[166])*v[54];
11377 v[590]=v[55]/(v[162]*v[206]);
11378 v[604]=v[206]*v[590];
11379 v[222]=2e0*v[195]*v[53]+v[591];
11380 v[223]=2e0*v[200]*v[53]+v[591];
11381 v[226]=(-(v[151]*(v[168]+v[140]*v[88]+v[144]*v[92]+v[145]*v[94]-v[144]*v[96]))+v[153]*(v[168]
11382 +v[139]*v[83]+v[143]*v[92]-v[143]*v[94]+v[147]*v[96])+v[148]*(v[171]+v[140]*v[89]+v[144]*v[93]
11383 +v[145]*v[95]-v[144]*v[97])-v[150]*(v[171]+v[139]*v[87]+v[143]*v[93]-v[143]*v[95]+v[147]*v[97]))
11384 /v[162];
11385 v[228]=(-(v[153]*v[178])+v[151]*v[179])*v[206]*v[590];
11386 v[229]=(v[150]*v[178]-v[148]*v[179])*v[206]*v[590];
11387 v[236]=-1e0*(v[164]*v[190]+v[165]*v[191])*v[53];
11388 v[237]=(v[153]*v[228]-v[150]*v[229])/v[162];
11389 v[238]=(-(v[151]*v[228])+v[148]*v[229])/v[162];
11390 v[239]=(-(v[150]*v[223])+v[153]*v[236])/v[162];
11391 v[245]=v[143]*v[239];
11392 v[240]=(v[148]*v[223]-v[151]*v[236])/v[162];
11393 v[246]=v[144]*v[240];
11394 v[241]=(v[153]*v[222]-v[150]*v[236])/v[162];
11395 v[243]=v[143]*v[241];
11396 v[242]=(-(v[151]*v[222])+v[148]*v[236])/v[162];
11397 v[244]=v[144]*v[242];
11398 v[5023]=v[139]*v[241];
11399 v[5024]=v[139]*v[239];
11400 v[5025]=v[140]*v[242];
11401 v[5026]=v[140]*v[240];
11402 v[5027]=v[142]*(v[241]+v[242]);
11403 v[5028]=v[142]*(v[239]+v[240]);
11404 v[5029]=v[243]+v[244];
11405 v[5030]=v[245]+v[246];
11406 v[5031]=v[145]*v[242]-v[243];
11407 v[5032]=v[145]*v[240]-v[245];
11408 v[5033]=v[147]*v[241]-v[244];
11409 v[5034]=v[147]*v[239]-v[246];
11410 v[5035]=-(v[115]*v[226])+v[237];
11411 v[5036]=-(v[117]*v[226])+v[238];
11412 v[5037]=v[126]*v[226]-v[237]-v[238];
11413 for(i233=1;i233<=15;i233++){
11414 v[253]=v[5161+i233];
11415 v[254]=v[5176+i233];
11416 v[595]=v[5191+i233]*v[86];
11417 v[286]=v[142]*v[595];
11418 v[285]=v[595]/v[162];
11419 v[256]=v[144]*v[5041+i233]+v[5056+i233];
11420 v[257]=v[143]*v[5071+i233]+v[5086+i233];
11421 v[258]=(-(v[151]*v[256])+v[153]*v[257])/v[162];
11422 v[259]=v[144]*v[5101+i233]+v[5116+i233];
11423 v[260]=v[143]*v[5131+i233]+v[5146+i233];
11424 v[261]=(v[148]*v[259]-v[150]*v[260])/v[162];
11425 v[269]=((v[148]*v[253]-v[150]*v[254])*v[604])/v[162];
11426 v[270]=((-(v[151]*v[253])+v[153]*v[254])*v[604])/v[162];
11427 v[264]=(2e0*(v[148]*v[256]-v[150]*v[257]-v[151]*v[259]+v[153]*v[260])*v[53])/v[162];
11428 v[606]=0.5e0*v[264];
11429 v[605]=0.5e0*v[264];
11430 v[268]=v[150]*v[269]-v[153]*v[270];
11431 v[271]=-(v[148]*v[269])+v[151]*v[270];
11432 v[272]=v[258]+v[261];
11433 v[274]=v[272]*v[51];
11434 v[273]=v[274]+2e0*v[261]*v[53];
11435 v[275]=v[274]+2e0*v[258]*v[53];
11436 v[276]=1e0*v[165]*v[275]-v[191]*v[605];
11437 v[277]=1e0*v[164]*v[273]-v[190]*v[606];
11438 v[278]=-1e0*v[191]*v[273]+v[165]*v[605];
11439 v[280]=-1e0*v[190]*v[275]+v[164]*v[606];
11440 v[281]=(v[153]*v[276]-v[150]*v[278])/v[162];
11441 v[293]=v[143]*v[281];
11442 v[282]=(-(v[151]*v[276])+v[148]*v[278])/v[162];
11443 v[294]=v[144]*v[282];
11444 v[283]=(-(v[150]*v[277])+v[153]*v[280])/v[162];
11445 v[289]=v[143]*v[283];
11446 v[284]=(v[148]*v[277]-v[151]*v[280])/v[162];
11447 v[290]=v[144]*v[284];
11448 v[5207]=v[139]*(v[283]+v[153]*v[285]);
11449 v[5208]=v[139]*(v[281]-v[150]*v[285]);
11450 v[5209]=v[140]*(v[284]-v[151]*v[285]);
11451 v[5210]=v[140]*(v[282]+v[148]*v[285]);
11452 v[5211]=v[142]*(v[283]+v[284])+v[286]*(v[607]+v[608]);
11453 v[5212]=v[142]*(v[281]+v[282])+v[286]*(v[609]+v[610]);
11454 v[5213]=v[289]+v[290]+(-v[287]+v[288])*v[595];
11455 v[5214]=v[293]+v[294]+(v[291]-v[292])*v[595];
11456 v[5215]=v[145]*v[284]-v[289]+v[595]*(-v[288]+v[611]);
11457 v[5216]=v[145]*v[282]-v[293]+v[595]*(v[292]+v[612]);
11458 v[5217]=v[147]*v[283]-v[290]+v[595]*(v[287]+v[613]);
11459 v[5218]=v[147]*v[281]-v[294]+v[595]*(-v[291]+v[614]);
11460 v[5219]=v[268]-v[115]*v[272];
11461 v[5220]=v[271]-v[117]*v[272];
11462 v[5221]=-v[268]-v[271]+v[126]*v[272];
11463 p[i233-1]+=v[155]*v[5022+i233];
11464 for(i250=1;i250<=15;i250++){
11465 s[i233-1][i250-1]+=v[155]*v[5206+i250];
11466 };/* end for */
11467 };/* end for */
11468 };/* end for */
11469 if(idata[ID_CurrentElement]==1e0){
11470 ++idata[ID_NoMessages];
11471 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11472 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","ElementNumber: ",(double)idata[ID_CurrentElement]
11473 ," Time: ",(double)rdata[RD_Time]," TimeSteps: ",(double)idata[ID_Step]," IterationSteps: ",
11474 (double)idata[ID_Iteration]);
11475 fclose(SMSFile);};};
11476 ++idata[ID_NoMessages];
11477 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11478 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Emodul: ",(double)v[49]," Poissonsratio: ",(double)v[50]
11479 ," InitialSolidVolumeFraction: ",(double)v[54]);
11480 fclose(SMSFile);};};
11481 ++idata[ID_NoMessages];
11482 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11483 fprintf(SMSFile,"\n%s %g %s %g ","TimeIncrement :",(double)rdata[RD_TimeIncrement]
11484 ," LoadIncrement: ",(double)rdata[RD_MultiplierIncrement]);
11485 fclose(SMSFile);};};
11486 ++idata[ID_NoMessages];
11487 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11488 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[0]," CoorX: ",(double
11489 )nd[0]->X[0]," CoorY: ",(double)nd[0]->X[1]," NumberDOF: ",(double)nd[0]->id.NoDOF);
11490 fclose(SMSFile);};};
11491 ++idata[ID_NoMessages];
11492 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11493 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[0]->DOF[0]);
11494 fclose(SMSFile);};};
11495 ++idata[ID_NoMessages];
11496 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11497 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[0]->DOF[1]);
11498 fclose(SMSFile);};};
11499 ++idata[ID_NoMessages];
11500 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11501 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[1]," CoorX: ",(double
11502 )nd[1]->X[0]," CoorY: ",(double)nd[1]->X[1]," NumberDOF: ",(double)nd[1]->id.NoDOF);
11503 fclose(SMSFile);};};
11504 ++idata[ID_NoMessages];
11505 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11506 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[1]->DOF[0]);
11507 fclose(SMSFile);};};
11508 ++idata[ID_NoMessages];
11509 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11510 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[1]->DOF[1]);
11511 fclose(SMSFile);};};
11512 ++idata[ID_NoMessages];
11513 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11514 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[2]," CoorX: ",(double
11515 )nd[2]->X[0]," CoorY: ",(double)nd[2]->X[1]," NumberDOF: ",(double)nd[2]->id.NoDOF);
11516 fclose(SMSFile);};};
11517 ++idata[ID_NoMessages];
11518 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11519 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[2]->DOF[0]);
11520 fclose(SMSFile);};};
11521 ++idata[ID_NoMessages];
11522 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11523 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[2]->DOF[1]);
11524 fclose(SMSFile);};};
11525 ++idata[ID_NoMessages];
11526 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11527 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[3]," CoorX: ",(double
11528 )nd[3]->X[0]," CoorY: ",(double)nd[3]->X[1]," NumberDOF: ",(double)nd[3]->id.NoDOF);
11529 fclose(SMSFile);};};
11530 ++idata[ID_NoMessages];
11531 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11532 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[3]->DOF[0]);
11533 fclose(SMSFile);};};
11534 ++idata[ID_NoMessages];
11535 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11536 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[3]->DOF[1]);
11537 fclose(SMSFile);};};
11538 ++idata[ID_NoMessages];
11539 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11540 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[4]," CoorX: ",(double
11541 )nd[4]->X[0]," CoorY: ",(double)nd[4]->X[1]," NumberDOF: ",(double)nd[4]->id.NoDOF);
11542 fclose(SMSFile);};};
11543 ++idata[ID_NoMessages];
11544 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11545 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[4]->DOF[0]);
11546 fclose(SMSFile);};};
11547 ++idata[ID_NoMessages];
11548 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11549 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[4]->DOF[1]);
11550 fclose(SMSFile);};};
11551 ++idata[ID_NoMessages];
11552 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11553 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[5]," CoorX: ",(double
11554 )nd[5]->X[0]," CoorY: ",(double)nd[5]->X[1]," NumberDOF: ",(double)nd[5]->id.NoDOF);
11555 fclose(SMSFile);};};
11556 ++idata[ID_NoMessages];
11557 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11558 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[5]->DOF[0]);
11559 fclose(SMSFile);};};
11560 ++idata[ID_NoMessages];
11561 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11562 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[5]->DOF[1]);
11563 fclose(SMSFile);};};
11564 ++idata[ID_NoMessages];
11565 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11566 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[6]," CoorX: ",(double
11567 )nd[6]->X[0]," CoorY: ",(double)nd[6]->X[1]," NumberDOF: ",(double)nd[6]->id.NoDOF);
11568 fclose(SMSFile);};};
11569 ++idata[ID_NoMessages];
11570 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11571 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[6]->DOF[0]);
11572 fclose(SMSFile);};};
11573 ++idata[ID_NoMessages];
11574 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11575 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[7]," CoorX: ",(double
11576 )nd[7]->X[0]," CoorY: ",(double)nd[7]->X[1]," NumberDOF: ",(double)nd[7]->id.NoDOF);
11577 fclose(SMSFile);};};
11578 ++idata[ID_NoMessages];
11579 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11580 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[7]->DOF[0]);
11581 fclose(SMSFile);};};
11582 ++idata[ID_NoMessages];
11583 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11584 fprintf(SMSFile,"\n%s %g %s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[8]," CoorX: ",(double
11585 )nd[8]->X[0]," CoorY: ",(double)nd[8]->X[1]," NumberDOF: ",(double)nd[8]->id.NoDOF);
11586 fclose(SMSFile);};};
11587 ++idata[ID_NoMessages];
11588 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11589 fprintf(SMSFile,"\n%s %g ","DOFposition: ",(double)nd[8]->DOF[0]);
11590 fclose(SMSFile);};};
11591 ++idata[ID_NoMessages];
11592 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11593 fprintf(SMSFile,"\n%s %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g "
11594 ,"hp or h1 field: ",(double)v[57],(double)v[58],(double)v[59],(double)v[60],(double)v[61],(double
11595 )v[62],(double)v[63],(double)v[64],(double)v[65],(double)v[66],(double)v[67],(double)v[68],(double
11596 )v[69],(double)v[70],(double)v[71],(double)v[72],(double)v[73],(double)v[74],(double)v[75],(double
11597 )v[76],(double)v[77],(double)v[78],(double)v[79],(double)v[80]);
11598 fclose(SMSFile);};};
11599 ++idata[ID_NoMessages];
11600 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11601 fprintf(SMSFile,"\n%s %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g "
11602 ,"ht or h2 field: ",(double)v[83],(double)v[88],(double)v[90],(double)v[92],(double)v[94],(double
11603 )v[96],(double)v[87],(double)v[89],(double)v[91],(double)v[93],(double)v[95],(double)v[97],(double
11604 )v[98],(double)v[103],(double)v[105],(double)v[107],(double)v[109],(double)v[111],(double)v[102],
11605 (double)v[104],(double)v[106],(double)v[108],(double)v[110],(double)v[112]);
11606 fclose(SMSFile);};};
11607 ++idata[ID_NoMessages];
11608 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11609 fprintf(SMSFile,"\n%s %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ","ap or up field: ",(double
11610 )v[34],(double)v[35],(double)v[36],(double)v[37],(double)v[38],(double)v[39],(double)v[40],(double
11611 )v[41],(double)v[42],(double)v[43],(double)v[44],(double)v[45],(double)nd[6]->ap[0],(double)nd[7]
11612 ->ap[0],(double)nd[8]->ap[0]);
11613 fclose(SMSFile);};};
11614 ++idata[ID_NoMessages];
11615 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11616 fprintf(SMSFile,"\n%s %g %g %g %g %g %g %g %g %g %g %g %g %g %g %g ","at or ul field: ",(double
11617 )v[19],(double)v[20],(double)v[21],(double)v[22],(double)v[23],(double)v[24],(double)v[25],(double
11618 )v[26],(double)v[27],(double)v[28],(double)v[29],(double)v[30],(double)v[31],(double)v[32],(double
11619 )v[33]);
11620 fclose(SMSFile);};};
11621 ++idata[ID_NoMessages];
11622 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11623 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[0]," Ux: ",(double)nd[0]
11624 ->at[0]," Uy: ",(double)nd[0]->at[1]);
11625 fclose(SMSFile);};};
11626 ++idata[ID_NoMessages];
11627 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11628 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[1]," Ux: ",(double)nd[1]
11629 ->at[0]," Uy: ",(double)nd[1]->at[1]);
11630 fclose(SMSFile);};};
11631 ++idata[ID_NoMessages];
11632 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11633 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[2]," Ux: ",(double)nd[2]
11634 ->at[0]," Uy: ",(double)nd[2]->at[1]);
11635 fclose(SMSFile);};};
11636 ++idata[ID_NoMessages];
11637 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11638 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[3]," Ux: ",(double)nd[3]
11639 ->at[0]," Uy: ",(double)nd[3]->at[1]);
11640 fclose(SMSFile);};};
11641 ++idata[ID_NoMessages];
11642 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11643 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[4]," Ux: ",(double)nd[4]
11644 ->at[0]," Uy: ",(double)nd[4]->at[1]);
11645 fclose(SMSFile);};};
11646 ++idata[ID_NoMessages];
11647 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11648 fprintf(SMSFile,"\n%s %g %s %g %s %g ","Nodes: ",(double)ed->Nodes[5]," Ux: ",(double)nd[5]
11649 ->at[0]," Uy: ",(double)nd[5]->at[1]);
11650 fclose(SMSFile);};};
11651 ++idata[ID_NoMessages];
11652 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11653 fprintf(SMSFile,"\n%s %g %s %g ","Nodes: ",(double)ed->Nodes[6]," p: ",(double)nd[6]->at[0]);
11654 fclose(SMSFile);};};
11655 ++idata[ID_NoMessages];
11656 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11657 fprintf(SMSFile,"\n%s %g %s %g ","Nodes: ",(double)ed->Nodes[7]," p: ",(double)nd[7]->at[0]);
11658 fclose(SMSFile);};};
11659 ++idata[ID_NoMessages];
11660 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11661 fprintf(SMSFile,"\n%s %g %s %g ","Nodes: ",(double)ed->Nodes[8]," p: ",(double)nd[8]->at[0]);
11662 fclose(SMSFile);};};
11663 ++idata[ID_NoMessages];
11664 if(1){SMSFile=fopen("myoutput.dat","a");if(SMSFile!=NULL){
11665 fprintf(SMSFile,"\n%s ","%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
11666 fclose(SMSFile);};};
11667 } else {
11668 };
11669};
11670
11671
11672// Added 07.09.2020 CH
11673template <class SC, class LO, class GO, class NO>
11674void FE<SC,LO,GO,NO>::SKR_Biot3D(double* v, ElementSpec *es, ElementData *ed, NodeSpec **ns, NodeData **nd, double *rdata, int *idata, double *p, double **s)
11675{
11676 int i254,i256,i438,i455;
11677 v[1514]=0e0;
11678 v[1515]=0e0;
11679 v[1516]=0e0;
11680 v[1517]=0e0;
11681 v[1518]=0e0;
11682 v[1519]=0e0;
11683 v[1520]=0e0;
11684 v[1521]=0e0;
11685 v[1522]=0e0;
11686 v[1523]=0e0;
11687 v[1524]=0e0;
11688 v[1525]=0e0;
11689 v[1526]=0e0;
11690 v[1527]=0e0;
11691 v[1528]=0e0;
11692 v[1529]=0e0;
11693 v[1530]=0e0;
11694 v[1531]=0e0;
11695 v[1532]=0e0;
11696 v[1533]=0e0;
11697 v[1534]=0e0;
11698 v[1535]=0e0;
11699 v[1536]=0e0;
11700 v[1537]=0e0;
11701 v[1538]=0e0;
11702 v[1539]=0e0;
11703 v[1540]=0e0;
11704 v[1541]=0e0;
11705 v[1542]=0e0;
11706 v[1543]=0e0;
11707 v[1544]=1e0;
11708 v[1545]=0e0;
11709 v[1546]=0e0;
11710 v[1547]=-1e0;
11711 v[1480]=0e0;
11712 v[1481]=0e0;
11713 v[1482]=0e0;
11714 v[1483]=0e0;
11715 v[1484]=0e0;
11716 v[1485]=0e0;
11717 v[1486]=0e0;
11718 v[1487]=0e0;
11719 v[1488]=0e0;
11720 v[1489]=0e0;
11721 v[1490]=0e0;
11722 v[1491]=0e0;
11723 v[1492]=0e0;
11724 v[1493]=0e0;
11725 v[1494]=0e0;
11726 v[1495]=0e0;
11727 v[1496]=0e0;
11728 v[1497]=0e0;
11729 v[1498]=0e0;
11730 v[1499]=0e0;
11731 v[1500]=0e0;
11732 v[1501]=0e0;
11733 v[1502]=0e0;
11734 v[1503]=0e0;
11735 v[1504]=0e0;
11736 v[1505]=0e0;
11737 v[1506]=0e0;
11738 v[1507]=0e0;
11739 v[1508]=0e0;
11740 v[1509]=0e0;
11741 v[1510]=0e0;
11742 v[1511]=1e0;
11743 v[1512]=0e0;
11744 v[1513]=-1e0;
11745 v[1446]=0e0;
11746 v[1447]=0e0;
11747 v[1448]=0e0;
11748 v[1449]=0e0;
11749 v[1450]=0e0;
11750 v[1451]=0e0;
11751 v[1452]=0e0;
11752 v[1453]=0e0;
11753 v[1454]=0e0;
11754 v[1455]=0e0;
11755 v[1456]=0e0;
11756 v[1457]=0e0;
11757 v[1458]=0e0;
11758 v[1459]=0e0;
11759 v[1460]=0e0;
11760 v[1461]=0e0;
11761 v[1462]=0e0;
11762 v[1463]=0e0;
11763 v[1464]=0e0;
11764 v[1465]=0e0;
11765 v[1466]=0e0;
11766 v[1467]=0e0;
11767 v[1468]=0e0;
11768 v[1469]=0e0;
11769 v[1470]=0e0;
11770 v[1471]=0e0;
11771 v[1472]=0e0;
11772 v[1473]=0e0;
11773 v[1474]=0e0;
11774 v[1475]=0e0;
11775 v[1476]=0e0;
11776 v[1477]=0e0;
11777 v[1478]=1e0;
11778 v[1479]=-1e0;
11779 v[1]=nd[0]->X[0];
11780 v[2]=nd[0]->X[1];
11781 v[3]=nd[0]->X[2];
11782 v[4]=nd[1]->X[0];
11783 v[5]=nd[1]->X[1];
11784 v[6]=nd[1]->X[2];
11785 v[7]=nd[2]->X[0];
11786 v[8]=nd[2]->X[1];
11787 v[9]=nd[2]->X[2];
11788 v[10]=nd[3]->X[0];
11789 v[11]=nd[3]->X[1];
11790 v[12]=nd[3]->X[2];
11791 v[13]=nd[4]->X[0];
11792 v[14]=nd[4]->X[1];
11793 v[15]=nd[4]->X[2];
11794 v[16]=nd[5]->X[0];
11795 v[17]=nd[5]->X[1];
11796 v[18]=nd[5]->X[2];
11797 v[19]=nd[6]->X[0];
11798 v[20]=nd[6]->X[1];
11799 v[21]=nd[6]->X[2];
11800 v[22]=nd[7]->X[0];
11801 v[23]=nd[7]->X[1];
11802 v[24]=nd[7]->X[2];
11803 v[25]=nd[8]->X[0];
11804 v[26]=nd[8]->X[1];
11805 v[27]=nd[8]->X[2];
11806 v[28]=nd[9]->X[0];
11807 v[29]=nd[9]->X[1];
11808 v[30]=nd[9]->X[2];
11809 v[43]=nd[0]->at[0];
11810 v[44]=nd[0]->at[1];
11811 v[45]=nd[0]->at[2];
11812 v[46]=nd[1]->at[0];
11813 v[47]=nd[1]->at[1];
11814 v[48]=nd[1]->at[2];
11815 v[49]=nd[2]->at[0];
11816 v[50]=nd[2]->at[1];
11817 v[51]=nd[2]->at[2];
11818 v[52]=nd[3]->at[0];
11819 v[53]=nd[3]->at[1];
11820 v[54]=nd[3]->at[2];
11821 v[55]=nd[4]->at[0];
11822 v[56]=nd[4]->at[1];
11823 v[57]=nd[4]->at[2];
11824 v[58]=nd[5]->at[0];
11825 v[59]=nd[5]->at[1];
11826 v[60]=nd[5]->at[2];
11827 v[61]=nd[6]->at[0];
11828 v[62]=nd[6]->at[1];
11829 v[63]=nd[6]->at[2];
11830 v[64]=nd[7]->at[0];
11831 v[65]=nd[7]->at[1];
11832 v[66]=nd[7]->at[2];
11833 v[67]=nd[8]->at[0];
11834 v[68]=nd[8]->at[1];
11835 v[69]=nd[8]->at[2];
11836 v[70]=nd[9]->at[0];
11837 v[71]=nd[9]->at[1];
11838 v[72]=nd[9]->at[2];
11839 v[73]=nd[10]->at[0];
11840 v[74]=nd[11]->at[0];
11841 v[75]=nd[12]->at[0];
11842 v[76]=nd[13]->at[0];
11843 v[388]=v[75]-v[76];
11844 v[387]=v[74]-v[76];
11845 v[386]=v[73]-v[76];
11846 v[112]=es->Data[1];
11847 v[962]=es->Data[0]/(1e0+v[112]);
11848 v[113]=(v[112]*v[962])/(1e0-2e0*v[112]);
11849 v[115]=v[962]/2e0;
11850 v[116]=es->Data[2];
11851 v[117]=es->Data[3];
11852 v[118]=es->Data[4];
11853 v[119]=es->Data[5];
11854 v[121]=es->Data[7];
11855 v[122]=es->Data[8];
11856 v[1012]=v[121]-v[122];
11857 v[971]=es->Data[6]/(es->Data[9]*v[122]);
11858 v[433]=-(v[122]*v[971]);
11859 v[995]=v[118]*v[433];
11860 v[994]=v[117]*v[433];
11861 v[993]=v[116]*v[433];
11862 v[963]=-(es->Data[10]/es->Data[11]);
11863 v[190]=1e0+v[963];
11864 v[127]=rdata[RD_TimeIncrement];
11865 v[964]=v[127]*(1e0+v[963]/2e0);
11866 v[189]=-(v[963]/v[127]);
11867 v[188]=ed->hp[0]*v[190]+v[189]*(-nd[0]->ap[0]+v[43])+ed->hp[30]*v[964];
11868 v[192]=ed->hp[10]*v[190]+v[189]*(-nd[0]->ap[1]+v[44])+ed->hp[40]*v[964];
11869 v[193]=ed->hp[20]*v[190]+v[189]*(-nd[0]->ap[2]+v[45])+ed->hp[50]*v[964];
11870 v[194]=ed->hp[1]*v[190]+v[189]*(-nd[1]->ap[0]+v[46])+ed->hp[31]*v[964];
11871 v[195]=ed->hp[11]*v[190]+v[189]*(-nd[1]->ap[1]+v[47])+ed->hp[41]*v[964];
11872 v[196]=ed->hp[21]*v[190]+v[189]*(-nd[1]->ap[2]+v[48])+ed->hp[51]*v[964];
11873 v[197]=ed->hp[2]*v[190]+v[189]*(-nd[2]->ap[0]+v[49])+ed->hp[32]*v[964];
11874 v[198]=ed->hp[12]*v[190]+v[189]*(-nd[2]->ap[1]+v[50])+ed->hp[42]*v[964];
11875 v[199]=ed->hp[22]*v[190]+v[189]*(-nd[2]->ap[2]+v[51])+ed->hp[52]*v[964];
11876 v[200]=ed->hp[3]*v[190]+v[189]*(-nd[3]->ap[0]+v[52])+ed->hp[33]*v[964];
11877 v[201]=ed->hp[13]*v[190]+v[189]*(-nd[3]->ap[1]+v[53])+ed->hp[43]*v[964];
11878 v[202]=ed->hp[23]*v[190]+v[189]*(-nd[3]->ap[2]+v[54])+ed->hp[53]*v[964];
11879 v[203]=ed->hp[4]*v[190]+v[189]*(-nd[4]->ap[0]+v[55])+ed->hp[34]*v[964];
11880 v[204]=ed->hp[14]*v[190]+v[189]*(-nd[4]->ap[1]+v[56])+ed->hp[44]*v[964];
11881 v[205]=ed->hp[24]*v[190]+v[189]*(-nd[4]->ap[2]+v[57])+ed->hp[54]*v[964];
11882 v[206]=ed->hp[5]*v[190]+v[189]*(-nd[5]->ap[0]+v[58])+ed->hp[35]*v[964];
11883 v[207]=ed->hp[15]*v[190]+v[189]*(-nd[5]->ap[1]+v[59])+ed->hp[45]*v[964];
11884 v[208]=ed->hp[25]*v[190]+v[189]*(-nd[5]->ap[2]+v[60])+ed->hp[55]*v[964];
11885 v[209]=ed->hp[6]*v[190]+v[189]*(-nd[6]->ap[0]+v[61])+ed->hp[36]*v[964];
11886 v[210]=ed->hp[16]*v[190]+v[189]*(-nd[6]->ap[1]+v[62])+ed->hp[46]*v[964];
11887 v[211]=ed->hp[26]*v[190]+v[189]*(-nd[6]->ap[2]+v[63])+ed->hp[56]*v[964];
11888 v[212]=ed->hp[7]*v[190]+v[189]*(-nd[7]->ap[0]+v[64])+ed->hp[37]*v[964];
11889 v[213]=ed->hp[17]*v[190]+v[189]*(-nd[7]->ap[1]+v[65])+ed->hp[47]*v[964];
11890 v[214]=ed->hp[27]*v[190]+v[189]*(-nd[7]->ap[2]+v[66])+ed->hp[57]*v[964];
11891 v[215]=ed->hp[8]*v[190]+v[189]*(-nd[8]->ap[0]+v[67])+ed->hp[38]*v[964];
11892 v[216]=ed->hp[18]*v[190]+v[189]*(-nd[8]->ap[1]+v[68])+ed->hp[48]*v[964];
11893 v[217]=ed->hp[28]*v[190]+v[189]*(-nd[8]->ap[2]+v[69])+ed->hp[58]*v[964];
11894 v[218]=ed->hp[9]*v[190]+v[189]*(-nd[9]->ap[0]+v[70])+ed->hp[39]*v[964];
11895 v[219]=ed->hp[19]*v[190]+v[189]*(-nd[9]->ap[1]+v[71])+ed->hp[49]*v[964];
11896 v[220]=ed->hp[29]*v[190]+v[189]*(-nd[9]->ap[2]+v[72])+ed->hp[59]*v[964];
11897 for(i254=1;i254<=es->id.NoIntPoints;i254++){
11898 i256=4*(-1+i254);
11899 v[255]=es->IntPoints[i256];
11900 v[286]=4e0*v[255];
11901 v[374]=-(v[214]*v[286]);
11902 v[367]=-(v[213]*v[286]);
11903 v[360]=-(v[212]*v[286]);
11904 v[281]=-1e0+v[286];
11905 v[257]=es->IntPoints[1+i256];
11906 v[285]=4e0*v[257];
11907 v[333]=-(v[285]*v[69]);
11908 v[326]=-(v[285]*v[68]);
11909 v[319]=-(v[285]*v[67]);
11910 v[310]=-(v[27]*v[285]);
11911 v[303]=-(v[26]*v[285]);
11912 v[296]=-(v[25]*v[285]);
11913 v[282]=-1e0+v[285];
11914 v[258]=es->IntPoints[2+i256];
11915 v[287]=4e0*v[258];
11916 v[371]=-(v[220]*v[287]);
11917 v[364]=-(v[219]*v[287]);
11918 v[357]=-(v[218]*v[287]);
11919 v[331]=-(v[287]*v[72]);
11920 v[324]=-(v[287]*v[71]);
11921 v[317]=-(v[287]*v[70]);
11922 v[308]=-(v[287]*v[30]);
11923 v[301]=-(v[287]*v[29]);
11924 v[294]=-(v[28]*v[287]);
11925 v[283]=-1e0+v[287];
11926 v[260]=v[255]*(-1e0+2e0*v[255]);
11927 v[261]=v[257]*(-1e0+2e0*v[257]);
11928 v[262]=v[258]*(-1e0+2e0*v[258]);
11929 v[263]=1e0-v[255]-v[257]-v[258];
11930 v[1548]=0e0;
11931 v[1549]=0e0;
11932 v[1550]=0e0;
11933 v[1551]=0e0;
11934 v[1552]=0e0;
11935 v[1553]=0e0;
11936 v[1554]=0e0;
11937 v[1555]=0e0;
11938 v[1556]=0e0;
11939 v[1557]=0e0;
11940 v[1558]=0e0;
11941 v[1559]=0e0;
11942 v[1560]=0e0;
11943 v[1561]=0e0;
11944 v[1562]=0e0;
11945 v[1563]=0e0;
11946 v[1564]=0e0;
11947 v[1565]=0e0;
11948 v[1566]=0e0;
11949 v[1567]=0e0;
11950 v[1568]=0e0;
11951 v[1569]=0e0;
11952 v[1570]=0e0;
11953 v[1571]=0e0;
11954 v[1572]=0e0;
11955 v[1573]=0e0;
11956 v[1574]=0e0;
11957 v[1575]=0e0;
11958 v[1576]=0e0;
11959 v[1577]=0e0;
11960 v[1578]=v[255];
11961 v[1579]=v[257];
11962 v[1580]=v[258];
11963 v[1581]=v[263];
11964 v[288]=-4e0*v[263];
11965 v[291]=-v[287]-v[288];
11966 v[290]=-v[285]-v[288];
11967 v[289]=-v[286]-v[288];
11968 v[284]=1e0+v[288];
11969 v[1412]=0e0;
11970 v[1413]=0e0;
11971 v[1414]=v[281];
11972 v[1415]=0e0;
11973 v[1416]=0e0;
11974 v[1417]=0e0;
11975 v[1418]=0e0;
11976 v[1419]=0e0;
11977 v[1420]=0e0;
11978 v[1421]=0e0;
11979 v[1422]=0e0;
11980 v[1423]=v[284];
11981 v[1424]=0e0;
11982 v[1425]=0e0;
11983 v[1426]=v[285];
11984 v[1427]=0e0;
11985 v[1428]=0e0;
11986 v[1429]=0e0;
11987 v[1430]=0e0;
11988 v[1431]=0e0;
11989 v[1432]=v[287];
11990 v[1433]=0e0;
11991 v[1434]=0e0;
11992 v[1435]=v[289];
11993 v[1436]=0e0;
11994 v[1437]=0e0;
11995 v[1438]=-v[285];
11996 v[1439]=0e0;
11997 v[1440]=0e0;
11998 v[1441]=-v[287];
11999 v[1442]=0e0;
12000 v[1443]=0e0;
12001 v[1444]=0e0;
12002 v[1445]=0e0;
12003 v[1378]=0e0;
12004 v[1379]=0e0;
12005 v[1380]=0e0;
12006 v[1381]=0e0;
12007 v[1382]=0e0;
12008 v[1383]=v[282];
12009 v[1384]=0e0;
12010 v[1385]=0e0;
12011 v[1386]=0e0;
12012 v[1387]=0e0;
12013 v[1388]=0e0;
12014 v[1389]=v[284];
12015 v[1390]=0e0;
12016 v[1391]=0e0;
12017 v[1392]=v[286];
12018 v[1393]=0e0;
12019 v[1394]=0e0;
12020 v[1395]=v[287];
12021 v[1396]=0e0;
12022 v[1397]=0e0;
12023 v[1398]=0e0;
12024 v[1399]=0e0;
12025 v[1400]=0e0;
12026 v[1401]=-v[286];
12027 v[1402]=0e0;
12028 v[1403]=0e0;
12029 v[1404]=v[290];
12030 v[1405]=0e0;
12031 v[1406]=0e0;
12032 v[1407]=-v[287];
12033 v[1408]=0e0;
12034 v[1409]=0e0;
12035 v[1410]=0e0;
12036 v[1411]=0e0;
12037 v[1344]=0e0;
12038 v[1345]=0e0;
12039 v[1346]=0e0;
12040 v[1347]=0e0;
12041 v[1348]=0e0;
12042 v[1349]=0e0;
12043 v[1350]=0e0;
12044 v[1351]=0e0;
12045 v[1352]=v[283];
12046 v[1353]=0e0;
12047 v[1354]=0e0;
12048 v[1355]=v[284];
12049 v[1356]=0e0;
12050 v[1357]=0e0;
12051 v[1358]=0e0;
12052 v[1359]=0e0;
12053 v[1360]=0e0;
12054 v[1361]=v[285];
12055 v[1362]=0e0;
12056 v[1363]=0e0;
12057 v[1364]=v[286];
12058 v[1365]=0e0;
12059 v[1366]=0e0;
12060 v[1367]=-v[286];
12061 v[1368]=0e0;
12062 v[1369]=0e0;
12063 v[1370]=-v[285];
12064 v[1371]=0e0;
12065 v[1372]=0e0;
12066 v[1373]=v[291];
12067 v[1374]=0e0;
12068 v[1375]=0e0;
12069 v[1376]=0e0;
12070 v[1377]=0e0;
12071 v[1310]=0e0;
12072 v[1311]=v[281];
12073 v[1312]=0e0;
12074 v[1313]=0e0;
12075 v[1314]=0e0;
12076 v[1315]=0e0;
12077 v[1316]=0e0;
12078 v[1317]=0e0;
12079 v[1318]=0e0;
12080 v[1319]=0e0;
12081 v[1320]=v[284];
12082 v[1321]=0e0;
12083 v[1322]=0e0;
12084 v[1323]=v[285];
12085 v[1324]=0e0;
12086 v[1325]=0e0;
12087 v[1326]=0e0;
12088 v[1327]=0e0;
12089 v[1328]=0e0;
12090 v[1329]=v[287];
12091 v[1330]=0e0;
12092 v[1331]=0e0;
12093 v[1332]=v[289];
12094 v[1333]=0e0;
12095 v[1334]=0e0;
12096 v[1335]=-v[285];
12097 v[1336]=0e0;
12098 v[1337]=0e0;
12099 v[1338]=-v[287];
12100 v[1339]=0e0;
12101 v[1340]=0e0;
12102 v[1341]=0e0;
12103 v[1342]=0e0;
12104 v[1343]=0e0;
12105 v[1276]=0e0;
12106 v[1277]=0e0;
12107 v[1278]=0e0;
12108 v[1279]=0e0;
12109 v[1280]=v[282];
12110 v[1281]=0e0;
12111 v[1282]=0e0;
12112 v[1283]=0e0;
12113 v[1284]=0e0;
12114 v[1285]=0e0;
12115 v[1286]=v[284];
12116 v[1287]=0e0;
12117 v[1288]=0e0;
12118 v[1289]=v[286];
12119 v[1290]=0e0;
12120 v[1291]=0e0;
12121 v[1292]=v[287];
12122 v[1293]=0e0;
12123 v[1294]=0e0;
12124 v[1295]=0e0;
12125 v[1296]=0e0;
12126 v[1297]=0e0;
12127 v[1298]=-v[286];
12128 v[1299]=0e0;
12129 v[1300]=0e0;
12130 v[1301]=v[290];
12131 v[1302]=0e0;
12132 v[1303]=0e0;
12133 v[1304]=-v[287];
12134 v[1305]=0e0;
12135 v[1306]=0e0;
12136 v[1307]=0e0;
12137 v[1308]=0e0;
12138 v[1309]=0e0;
12139 v[1242]=0e0;
12140 v[1243]=0e0;
12141 v[1244]=0e0;
12142 v[1245]=0e0;
12143 v[1246]=0e0;
12144 v[1247]=0e0;
12145 v[1248]=0e0;
12146 v[1249]=v[283];
12147 v[1250]=0e0;
12148 v[1251]=0e0;
12149 v[1252]=v[284];
12150 v[1253]=0e0;
12151 v[1254]=0e0;
12152 v[1255]=0e0;
12153 v[1256]=0e0;
12154 v[1257]=0e0;
12155 v[1258]=v[285];
12156 v[1259]=0e0;
12157 v[1260]=0e0;
12158 v[1261]=v[286];
12159 v[1262]=0e0;
12160 v[1263]=0e0;
12161 v[1264]=-v[286];
12162 v[1265]=0e0;
12163 v[1266]=0e0;
12164 v[1267]=-v[285];
12165 v[1268]=0e0;
12166 v[1269]=0e0;
12167 v[1270]=v[291];
12168 v[1271]=0e0;
12169 v[1272]=0e0;
12170 v[1273]=0e0;
12171 v[1274]=0e0;
12172 v[1275]=0e0;
12173 v[1208]=v[281];
12174 v[1209]=0e0;
12175 v[1210]=0e0;
12176 v[1211]=0e0;
12177 v[1212]=0e0;
12178 v[1213]=0e0;
12179 v[1214]=0e0;
12180 v[1215]=0e0;
12181 v[1216]=0e0;
12182 v[1217]=v[284];
12183 v[1218]=0e0;
12184 v[1219]=0e0;
12185 v[1220]=v[285];
12186 v[1221]=0e0;
12187 v[1222]=0e0;
12188 v[1223]=0e0;
12189 v[1224]=0e0;
12190 v[1225]=0e0;
12191 v[1226]=v[287];
12192 v[1227]=0e0;
12193 v[1228]=0e0;
12194 v[1229]=v[289];
12195 v[1230]=0e0;
12196 v[1231]=0e0;
12197 v[1232]=-v[285];
12198 v[1233]=0e0;
12199 v[1234]=0e0;
12200 v[1235]=-v[287];
12201 v[1236]=0e0;
12202 v[1237]=0e0;
12203 v[1238]=0e0;
12204 v[1239]=0e0;
12205 v[1240]=0e0;
12206 v[1241]=0e0;
12207 v[1174]=0e0;
12208 v[1175]=0e0;
12209 v[1176]=0e0;
12210 v[1177]=v[282];
12211 v[1178]=0e0;
12212 v[1179]=0e0;
12213 v[1180]=0e0;
12214 v[1181]=0e0;
12215 v[1182]=0e0;
12216 v[1183]=v[284];
12217 v[1184]=0e0;
12218 v[1185]=0e0;
12219 v[1186]=v[286];
12220 v[1187]=0e0;
12221 v[1188]=0e0;
12222 v[1189]=v[287];
12223 v[1190]=0e0;
12224 v[1191]=0e0;
12225 v[1192]=0e0;
12226 v[1193]=0e0;
12227 v[1194]=0e0;
12228 v[1195]=-v[286];
12229 v[1196]=0e0;
12230 v[1197]=0e0;
12231 v[1198]=v[290];
12232 v[1199]=0e0;
12233 v[1200]=0e0;
12234 v[1201]=-v[287];
12235 v[1202]=0e0;
12236 v[1203]=0e0;
12237 v[1204]=0e0;
12238 v[1205]=0e0;
12239 v[1206]=0e0;
12240 v[1207]=0e0;
12241 v[1140]=0e0;
12242 v[1141]=0e0;
12243 v[1142]=0e0;
12244 v[1143]=0e0;
12245 v[1144]=0e0;
12246 v[1145]=0e0;
12247 v[1146]=v[283];
12248 v[1147]=0e0;
12249 v[1148]=0e0;
12250 v[1149]=v[284];
12251 v[1150]=0e0;
12252 v[1151]=0e0;
12253 v[1152]=0e0;
12254 v[1153]=0e0;
12255 v[1154]=0e0;
12256 v[1155]=v[285];
12257 v[1156]=0e0;
12258 v[1157]=0e0;
12259 v[1158]=v[286];
12260 v[1159]=0e0;
12261 v[1160]=0e0;
12262 v[1161]=-v[286];
12263 v[1162]=0e0;
12264 v[1163]=0e0;
12265 v[1164]=-v[285];
12266 v[1165]=0e0;
12267 v[1166]=0e0;
12268 v[1167]=v[291];
12269 v[1168]=0e0;
12270 v[1169]=0e0;
12271 v[1170]=0e0;
12272 v[1171]=0e0;
12273 v[1172]=0e0;
12274 v[1173]=0e0;
12275 v[370]=v[202]*v[284];
12276 v[977]=-(v[217]*v[285])+v[370];
12277 v[363]=v[201]*v[284];
12278 v[976]=-(v[216]*v[285])+v[363];
12279 v[356]=v[200]*v[284];
12280 v[975]=-(v[215]*v[285])+v[356];
12281 v[330]=v[284]*v[54];
12282 v[965]=v[330]-v[286]*v[66];
12283 v[335]=v[333]+v[283]*v[51]+v[285]*v[60]+v[286]*v[63]+v[291]*v[72]+v[965];
12284 v[332]=v[331]+v[282]*v[48]+v[286]*v[57]+v[287]*v[60]+v[290]*v[69]+v[965];
12285 v[329]=v[330]+v[331]+v[333]+v[281]*v[45]+v[285]*v[57]+v[287]*v[63]+v[289]*v[66];
12286 v[323]=v[284]*v[53];
12287 v[966]=v[323]-v[286]*v[65];
12288 v[328]=v[326]+v[283]*v[50]+v[285]*v[59]+v[286]*v[62]+v[291]*v[71]+v[966];
12289 v[325]=v[324]+v[282]*v[47]+v[286]*v[56]+v[287]*v[59]+v[290]*v[68]+v[966];
12290 v[322]=v[323]+v[324]+v[326]+v[281]*v[44]+v[285]*v[56]+v[287]*v[62]+v[289]*v[65];
12291 v[316]=v[284]*v[52];
12292 v[967]=v[316]-v[286]*v[64];
12293 v[321]=v[319]+v[283]*v[49]+v[285]*v[58]+v[286]*v[61]+v[291]*v[70]+v[967];
12294 v[318]=v[317]+v[282]*v[46]+v[286]*v[55]+v[287]*v[58]+v[290]*v[67]+v[967];
12295 v[315]=v[316]+v[317]+v[319]+v[281]*v[43]+v[285]*v[55]+v[287]*v[61]+v[289]*v[64];
12296 v[307]=v[12]*v[284];
12297 v[968]=-(v[24]*v[286])+v[307];
12298 v[312]=v[18]*v[285]+v[21]*v[286]+v[291]*v[30]+v[310]+v[283]*v[9]+v[968];
12299 v[309]=v[15]*v[286]+v[18]*v[287]+v[27]*v[290]+v[308]+v[282]*v[6]+v[968];
12300 v[306]=v[15]*v[285]+v[21]*v[287]+v[24]*v[289]+v[281]*v[3]+v[307]+v[308]+v[310];
12301 v[300]=v[11]*v[284];
12302 v[969]=-(v[23]*v[286])+v[300];
12303 v[305]=v[17]*v[285]+v[20]*v[286]+v[29]*v[291]+v[303]+v[283]*v[8]+v[969];
12304 v[302]=v[14]*v[286]+v[17]*v[287]+v[26]*v[290]+v[301]+v[282]*v[5]+v[969];
12305 v[340]=-(v[305]*v[309])+v[302]*v[312];
12306 v[299]=v[2]*v[281]+v[14]*v[285]+v[20]*v[287]+v[23]*v[289]+v[300]+v[301]+v[303];
12307 v[342]=-(v[302]*v[306])+v[299]*v[309];
12308 v[341]=v[305]*v[306]-v[299]*v[312];
12309 v[293]=v[10]*v[284];
12310 v[970]=-(v[22]*v[286])+v[293];
12311 v[298]=v[16]*v[285]+v[19]*v[286]+v[28]*v[291]+v[296]+v[283]*v[7]+v[970];
12312 v[295]=v[13]*v[286]+v[16]*v[287]+v[25]*v[290]+v[294]+v[282]*v[4]+v[970];
12313 v[348]=-(v[298]*v[302])+v[295]*v[305];
12314 v[344]=v[298]*v[309]-v[295]*v[312];
12315 v[292]=v[1]*v[281]+v[13]*v[285]+v[19]*v[287]+v[22]*v[289]+v[293]+v[294]+v[296];
12316 v[350]=-(v[295]*v[299])+v[292]*v[302];
12317 v[349]=v[298]*v[299]-v[292]*v[305];
12318 v[346]=v[295]*v[306]-v[292]*v[309];
12319 v[345]=-(v[298]*v[306])+v[292]*v[312];
12320 v[336]=v[292]*v[340]+v[295]*v[341]+v[298]*v[342];
12321 v[981]=v[115]/(v[336]*v[336]);
12322 v[972]=v[115]/v[336];
12323 v[480]=v[971]/v[336];
12324 v[521]=v[350]/v[336];
12325 v[520]=v[349]/v[336];
12326 v[1027]=v[520]+v[521];
12327 v[1021]=v[287]*v[520]+v[285]*v[521];
12328 v[519]=v[348]/v[336];
12329 v[1030]=v[519]+v[521];
12330 v[1024]=v[287]*v[519]+v[286]*v[521];
12331 v[1018]=v[285]*v[519]+v[286]*v[520];
12332 v[985]=v[519]+v[520];
12333 v[1015]=v[521]+v[985];
12334 v[518]=v[346]/v[336];
12335 v[517]=v[345]/v[336];
12336 v[1026]=v[517]+v[518];
12337 v[1020]=v[287]*v[517]+v[285]*v[518];
12338 v[516]=v[344]/v[336];
12339 v[1029]=v[516]+v[518];
12340 v[1023]=v[287]*v[516]+v[286]*v[518];
12341 v[1017]=v[285]*v[516]+v[286]*v[517];
12342 v[984]=v[516]+v[517];
12343 v[1014]=v[518]+v[984];
12344 v[515]=v[342]/v[336];
12345 v[514]=v[341]/v[336];
12346 v[1025]=v[514]+v[515];
12347 v[1019]=v[287]*v[514]+v[285]*v[515];
12348 v[513]=v[340]/v[336];
12349 v[1028]=v[513]+v[515];
12350 v[1022]=v[287]*v[513]+v[286]*v[515];
12351 v[1016]=v[285]*v[513]+v[286]*v[514];
12352 v[983]=v[513]+v[514];
12353 v[1013]=v[515]+v[983];
12354 v[264]=v[263]*(-1e0+2e0*v[263]);
12355 v[265]=4e0*v[255]*v[257];
12356 v[266]=4e0*v[257]*v[258];
12357 v[267]=4e0*v[255]*v[258];
12358 v[268]=4e0*v[255]*v[263];
12359 v[269]=4e0*v[257]*v[263];
12360 v[270]=4e0*v[258]*v[263];
12361 v[1582]=0e0;
12362 v[1583]=0e0;
12363 v[1584]=v[260];
12364 v[1585]=0e0;
12365 v[1586]=0e0;
12366 v[1587]=v[261];
12367 v[1588]=0e0;
12368 v[1589]=0e0;
12369 v[1590]=v[262];
12370 v[1591]=0e0;
12371 v[1592]=0e0;
12372 v[1593]=v[264];
12373 v[1594]=0e0;
12374 v[1595]=0e0;
12375 v[1596]=v[265];
12376 v[1597]=0e0;
12377 v[1598]=0e0;
12378 v[1599]=v[266];
12379 v[1600]=0e0;
12380 v[1601]=0e0;
12381 v[1602]=v[267];
12382 v[1603]=0e0;
12383 v[1604]=0e0;
12384 v[1605]=v[268];
12385 v[1606]=0e0;
12386 v[1607]=0e0;
12387 v[1608]=v[269];
12388 v[1609]=0e0;
12389 v[1610]=0e0;
12390 v[1611]=v[270];
12391 v[1612]=0e0;
12392 v[1613]=0e0;
12393 v[1614]=0e0;
12394 v[1615]=0e0;
12395 v[1616]=0e0;
12396 v[1617]=v[260];
12397 v[1618]=0e0;
12398 v[1619]=0e0;
12399 v[1620]=v[261];
12400 v[1621]=0e0;
12401 v[1622]=0e0;
12402 v[1623]=v[262];
12403 v[1624]=0e0;
12404 v[1625]=0e0;
12405 v[1626]=v[264];
12406 v[1627]=0e0;
12407 v[1628]=0e0;
12408 v[1629]=v[265];
12409 v[1630]=0e0;
12410 v[1631]=0e0;
12411 v[1632]=v[266];
12412 v[1633]=0e0;
12413 v[1634]=0e0;
12414 v[1635]=v[267];
12415 v[1636]=0e0;
12416 v[1637]=0e0;
12417 v[1638]=v[268];
12418 v[1639]=0e0;
12419 v[1640]=0e0;
12420 v[1641]=v[269];
12421 v[1642]=0e0;
12422 v[1643]=0e0;
12423 v[1644]=v[270];
12424 v[1645]=0e0;
12425 v[1646]=0e0;
12426 v[1647]=0e0;
12427 v[1648]=0e0;
12428 v[1649]=0e0;
12429 v[1650]=v[260];
12430 v[1651]=0e0;
12431 v[1652]=0e0;
12432 v[1653]=v[261];
12433 v[1654]=0e0;
12434 v[1655]=0e0;
12435 v[1656]=v[262];
12436 v[1657]=0e0;
12437 v[1658]=0e0;
12438 v[1659]=v[264];
12439 v[1660]=0e0;
12440 v[1661]=0e0;
12441 v[1662]=v[265];
12442 v[1663]=0e0;
12443 v[1664]=0e0;
12444 v[1665]=v[266];
12445 v[1666]=0e0;
12446 v[1667]=0e0;
12447 v[1668]=v[267];
12448 v[1669]=0e0;
12449 v[1670]=0e0;
12450 v[1671]=v[268];
12451 v[1672]=0e0;
12452 v[1673]=0e0;
12453 v[1674]=v[269];
12454 v[1675]=0e0;
12455 v[1676]=0e0;
12456 v[1677]=v[270];
12457 v[1678]=0e0;
12458 v[1679]=0e0;
12459 v[1680]=0e0;
12460 v[1681]=0e0;
12461 v[1682]=0e0;
12462 v[1683]=0e0;
12463 v[314]=es->IntPoints[3+i256]*std::fabs(v[336]);
12464 v[393]=(v[315]*v[340]+v[318]*v[341]+v[321]*v[342])/v[336];
12465 v[396]=(v[322]*v[344]+v[325]*v[345]+v[328]*v[346])/v[336];
12466 v[398]=(v[329]*v[348]+v[332]*v[349]+v[335]*v[350])/v[336];
12467 v[974]=v[393]+v[396]+v[398];
12468 v[973]=-(v[255]*v[73])-v[257]*v[74]-v[258]*v[75]-v[263]*v[76]+v[113]*v[974];
12469 v[402]=(v[322]*v[340]+v[325]*v[341]+v[328]*v[342]+v[315]*v[344]+v[318]*v[345]+v[321]*v[346]
12470 )*v[972];
12471 v[403]=(v[329]*v[340]+v[332]*v[341]+v[335]*v[342]+v[315]*v[348]+v[318]*v[349]+v[321]*v[350]
12472 )*v[972];
12473 v[406]=(v[329]*v[344]+v[332]*v[345]+v[335]*v[346]+v[322]*v[348]+v[325]*v[349]+v[328]*v[350]
12474 )*v[972];
12475 v[408]=2e0*v[115]*v[393]+v[973];
12476 v[409]=2e0*v[115]*v[396]+v[973];
12477 v[410]=2e0*v[115]*v[398]+v[973];
12478 v[417]=-(v[119]*(-1e0+v[974]));
12479 v[426]=v[122]*(-1e0+v[417])-v[121]*v[417];
12480 v[425]=v[116]*v[426];
12481 v[427]=v[117]*v[426];
12482 v[428]=v[118]*v[426];
12483 v[430]=(v[341]*(v[194]*v[282]+v[203]*v[286]+v[206]*v[287]+v[215]*v[290]+v[356]+v[357]+v[360])
12484 +v[345]*(v[195]*v[282]+v[204]*v[286]+v[207]*v[287]+v[216]*v[290]+v[363]+v[364]+v[367])+v[349]*
12485 (v[196]*v[282]+v[205]*v[286]+v[208]*v[287]+v[217]*v[290]+v[370]+v[371]+v[374])+v[340]*
12486 (v[188]*v[281]+v[203]*v[285]+v[209]*v[287]+v[212]*v[289]+v[357]+v[975])+v[342]*(v[197]*v[283]
12487 +v[206]*v[285]+v[209]*v[286]+v[218]*v[291]+v[360]+v[975])+v[344]*(v[192]*v[281]+v[204]*v[285]
12488 +v[210]*v[287]+v[213]*v[289]+v[364]+v[976])+v[346]*(v[198]*v[283]+v[207]*v[285]+v[210]*v[286]
12489 +v[219]*v[291]+v[367]+v[976])+v[348]*(v[193]*v[281]+v[205]*v[285]+v[211]*v[287]+v[214]*v[289]
12490 +v[371]+v[977])+v[350]*(v[199]*v[283]+v[208]*v[285]+v[211]*v[286]+v[220]*v[291]+v[374]+v[977]))
12491 /v[336];
12492 v[432]=(v[340]*v[386]+v[341]*v[387]+v[342]*v[388])*v[480]+v[993];
12493 v[434]=(v[344]*v[386]+v[345]*v[387]+v[346]*v[388])*v[480]+v[994];
12494 v[435]=(v[348]*v[386]+v[349]*v[387]+v[350]*v[388])*v[480]+v[995];
12495 v[440]=(v[340]*v[432]+v[344]*v[434]+v[348]*v[435])/v[336];
12496 v[441]=(v[341]*v[432]+v[345]*v[434]+v[349]*v[435])/v[336];
12497 v[442]=(v[342]*v[432]+v[346]*v[434]+v[350]*v[435])/v[336];
12498 v[443]=(v[340]*v[403]+v[344]*v[406]+v[348]*v[410])/v[336];
12499 v[444]=(v[341]*v[403]+v[345]*v[406]+v[349]*v[410])/v[336];
12500 v[445]=(v[342]*v[403]+v[346]*v[406]+v[350]*v[410])/v[336];
12501 v[980]=v[444]+v[445];
12502 v[446]=(v[340]*v[402]+v[348]*v[406]+v[344]*v[409])/v[336];
12503 v[447]=(v[341]*v[402]+v[349]*v[406]+v[345]*v[409])/v[336];
12504 v[448]=(v[342]*v[402]+v[350]*v[406]+v[346]*v[409])/v[336];
12505 v[979]=v[447]+v[448];
12506 v[449]=(v[344]*v[402]+v[348]*v[403]+v[340]*v[408])/v[336];
12507 v[450]=(v[345]*v[402]+v[349]*v[403]+v[341]*v[408])/v[336];
12508 v[451]=(v[346]*v[402]+v[350]*v[403]+v[342]*v[408])/v[336];
12509 v[978]=v[450]+v[451];
12510 v[1102]=v[260]*v[425]+v[281]*v[449];
12511 v[1103]=v[260]*v[427]+v[281]*v[446];
12512 v[1104]=v[260]*v[428]+v[281]*v[443];
12513 v[1105]=v[261]*v[425]+v[282]*v[450];
12514 v[1106]=v[261]*v[427]+v[282]*v[447];
12515 v[1107]=v[261]*v[428]+v[282]*v[444];
12516 v[1108]=v[262]*v[425]+v[283]*v[451];
12517 v[1109]=v[262]*v[427]+v[283]*v[448];
12518 v[1110]=v[262]*v[428]+v[283]*v[445];
12519 v[1111]=v[264]*v[425]+v[284]*(v[449]+v[978]);
12520 v[1112]=v[264]*v[427]+v[284]*(v[446]+v[979]);
12521 v[1113]=v[264]*v[428]+v[284]*(v[443]+v[980]);
12522 v[1114]=v[265]*v[425]+v[285]*v[449]+v[286]*v[450];
12523 v[1115]=v[265]*v[427]+v[285]*v[446]+v[286]*v[447];
12524 v[1116]=v[265]*v[428]+v[285]*v[443]+v[286]*v[444];
12525 v[1117]=v[266]*v[425]+v[287]*v[450]+v[285]*v[451];
12526 v[1118]=v[266]*v[427]+v[287]*v[447]+v[285]*v[448];
12527 v[1119]=v[266]*v[428]+v[287]*v[444]+v[285]*v[445];
12528 v[1120]=v[267]*v[425]+v[287]*v[449]+v[286]*v[451];
12529 v[1121]=v[267]*v[427]+v[287]*v[446]+v[286]*v[448];
12530 v[1122]=v[267]*v[428]+v[287]*v[443]+v[286]*v[445];
12531 v[1123]=v[268]*v[425]+v[289]*v[449]-v[286]*v[978];
12532 v[1124]=v[268]*v[427]+v[289]*v[446]-v[286]*v[979];
12533 v[1125]=v[268]*v[428]+v[289]*v[443]-v[286]*v[980];
12534 v[1126]=v[269]*v[425]+v[290]*v[450]-v[285]*(v[449]+v[451]);
12535 v[1127]=v[269]*v[427]+v[290]*v[447]-v[285]*(v[446]+v[448]);
12536 v[1128]=v[269]*v[428]+v[290]*v[444]-v[285]*(v[443]+v[445]);
12537 v[1129]=v[270]*v[425]-v[287]*(v[449]+v[450])+v[291]*v[451];
12538 v[1130]=v[270]*v[427]-v[287]*(v[446]+v[447])+v[291]*v[448];
12539 v[1131]=v[270]*v[428]-v[287]*(v[443]+v[444])+v[291]*v[445];
12540 v[1132]=v[255]*v[430]+v[440];
12541 v[1133]=v[257]*v[430]+v[441];
12542 v[1134]=v[258]*v[430]+v[442];
12543 v[1135]=v[263]*v[430]-v[440]-v[441]-v[442];
12544 for(i438=1;i438<=34;i438++){
12545 v[458]=v[1139+i438];
12546 v[459]=v[1173+i438];
12547 v[460]=v[1207+i438];
12548 v[461]=v[1241+i438];
12549 v[462]=v[1275+i438];
12550 v[463]=v[1309+i438];
12551 v[464]=v[1343+i438];
12552 v[465]=v[1377+i438];
12553 v[466]=v[1411+i438];
12554 v[467]=v[1445+i438];
12555 v[468]=v[1479+i438];
12556 v[469]=v[1513+i438];
12557 v[470]=v[1547+i438];
12558 v[992]=-(v[287]*v[470]);
12559 v[991]=-(v[285]*v[470]);
12560 v[988]=-(v[286]*v[470]);
12561 v[986]=v[189]*v[470];
12562 v[512]=v[284]*v[986];
12563 v[511]=v[470]*v[521];
12564 v[510]=v[470]*v[518];
12565 v[509]=v[470]*v[515];
12566 v[508]=v[470]*v[520];
12567 v[507]=v[470]*v[517];
12568 v[506]=v[470]*v[514];
12569 v[505]=v[470]*v[519];
12570 v[504]=v[470]*v[516];
12571 v[503]=v[470]*v[513];
12572 v[471]=(v[342]*v[458]+v[341]*v[459]+v[340]*v[460])/v[336];
12573 v[472]=(v[346]*v[461]+v[345]*v[462]+v[344]*v[463])/v[336];
12574 v[497]=(v[346]*v[458]+v[345]*v[459]+v[344]*v[460]+v[342]*v[461]+v[341]*v[462]+v[340]*v[463]
12575 )*v[981];
12576 v[474]=(v[350]*v[464]+v[349]*v[465]+v[348]*v[466])/v[336];
12577 v[492]=(v[350]*v[461]+v[349]*v[462]+v[348]*v[463]+v[346]*v[464]+v[345]*v[465]+v[344]*v[466]
12578 )*v[981];
12579 v[493]=(v[350]*v[458]+v[349]*v[459]+v[348]*v[460]+v[342]*v[464]+v[341]*v[465]+v[340]*v[466]
12580 )*v[981];
12581 v[477]=(v[350]*v[467]+v[349]*v[468]+v[348]*v[469])/v[336];
12582 v[478]=(v[346]*v[467]+v[345]*v[468]+v[344]*v[469])/v[336];
12583 v[479]=(v[342]*v[467]+v[341]*v[468]+v[340]*v[469])/v[336];
12584 v[481]=(v[348]*v[477]+v[344]*v[478]+v[340]*v[479])*v[480];
12585 v[482]=(v[349]*v[477]+v[345]*v[478]+v[341]*v[479])*v[480];
12586 v[483]=(v[350]*v[477]+v[346]*v[478]+v[342]*v[479])*v[480];
12587 v[485]=v[471]+v[472]+v[474];
12588 v[982]=v[1012]*v[119]*(v[118]*v[1581+i438]+v[117]*v[1615+i438]+v[116]*v[1649+i438])
12589 +v[113]*v[485];
12590 v[486]=2e0*v[115]*v[474]+v[982];
12591 v[489]=2e0*v[115]*v[472]+v[982];
12592 v[490]=2e0*v[115]*v[471]+v[982];
12593 v[491]=v[344]*v[492]+v[340]*v[493]+v[486]*v[519];
12594 v[494]=v[345]*v[492]+v[341]*v[493]+v[486]*v[520];
12595 v[495]=v[346]*v[492]+v[342]*v[493]+v[486]*v[521];
12596 v[990]=v[494]+v[495];
12597 v[496]=v[348]*v[492]+v[340]*v[497]+v[489]*v[516];
12598 v[498]=v[349]*v[492]+v[341]*v[497]+v[489]*v[517];
12599 v[499]=v[350]*v[492]+v[342]*v[497]+v[489]*v[518];
12600 v[989]=v[498]+v[499];
12601 v[500]=v[348]*v[493]+v[344]*v[497]+v[490]*v[513];
12602 v[501]=v[349]*v[493]+v[345]*v[497]+v[490]*v[514];
12603 v[502]=v[350]*v[493]+v[346]*v[497]+v[490]*v[515];
12604 v[987]=v[501]+v[502];
12605 v[1684]=v[281]*(v[500]+v[189]*v[503]);
12606 v[1685]=v[281]*(v[496]+v[189]*v[504]);
12607 v[1686]=v[281]*(v[491]+v[189]*v[505]);
12608 v[1687]=v[282]*(v[501]+v[189]*v[506]);
12609 v[1688]=v[282]*(v[498]+v[189]*v[507]);
12610 v[1689]=v[282]*(v[494]+v[189]*v[508]);
12611 v[1690]=v[283]*(v[502]+v[189]*v[509]);
12612 v[1691]=v[283]*(v[499]+v[189]*v[510]);
12613 v[1692]=v[283]*(v[495]+v[189]*v[511]);
12614 v[1693]=v[1013]*v[512]+v[284]*(v[500]+v[987]);
12615 v[1694]=v[1014]*v[512]+v[284]*(v[496]+v[989]);
12616 v[1695]=v[1015]*v[512]+v[284]*(v[491]+v[990]);
12617 v[1696]=v[285]*v[500]+v[286]*v[501]+v[1016]*v[986];
12618 v[1697]=v[285]*v[496]+v[286]*v[498]+v[1017]*v[986];
12619 v[1698]=v[285]*v[491]+v[286]*v[494]+v[1018]*v[986];
12620 v[1699]=v[287]*v[501]+v[285]*v[502]+v[1019]*v[986];
12621 v[1700]=v[287]*v[498]+v[285]*v[499]+v[1020]*v[986];
12622 v[1701]=v[287]*v[494]+v[285]*v[495]+v[1021]*v[986];
12623 v[1702]=v[287]*v[500]+v[286]*v[502]+v[1022]*v[986];
12624 v[1703]=v[287]*v[496]+v[286]*v[499]+v[1023]*v[986];
12625 v[1704]=v[287]*v[491]+v[286]*v[495]+v[1024]*v[986];
12626 v[1705]=v[289]*v[500]-v[286]*v[987]+v[189]*(v[289]*v[503]+v[1025]*v[988]);
12627 v[1706]=v[289]*v[496]+v[189]*(v[289]*v[504]+v[1026]*v[988])-v[286]*v[989];
12628 v[1707]=v[289]*v[491]+v[189]*(v[289]*v[505]+v[1027]*v[988])-v[286]*v[990];
12629 v[1708]=v[290]*v[501]-v[285]*(v[500]+v[502])+v[189]*(v[290]*v[506]+v[1028]*v[991]);
12630 v[1709]=v[290]*v[498]-v[285]*(v[496]+v[499])+v[189]*(v[290]*v[507]+v[1029]*v[991]);
12631 v[1710]=v[290]*v[494]-v[285]*(v[491]+v[495])+v[189]*(v[290]*v[508]+v[1030]*v[991]);
12632 v[1711]=-(v[287]*(v[500]+v[501]))+v[291]*v[502]+v[189]*(v[291]*v[509]+v[983]*v[992]);
12633 v[1712]=-(v[287]*(v[496]+v[498]))+v[291]*v[499]+v[189]*(v[291]*v[510]+v[984]*v[992]);
12634 v[1713]=-(v[287]*(v[491]+v[494]))+v[291]*v[495]+v[189]*(v[291]*v[511]+v[985]*v[992]);
12635 v[1714]=v[481]-v[255]*v[485];
12636 v[1715]=v[482]-v[257]*v[485];
12637 v[1716]=v[483]-v[258]*v[485];
12638 v[1717]=-v[481]-v[482]-v[483]-v[263]*v[485];
12639 p[i438-1]+=v[1101+i438]*v[314];
12640 for(i455=1;i455<=34;i455++){
12641 s[i438-1][i455-1]+=v[1683+i455]*v[314];
12642 };/* end for */
12643 };/* end for */
12644 };/* end for */
12645 };
12646
12647 /******************* S U B R O U T I N E *********************/
12648 void SPP(double v[1817],ElementSpec *es,ElementData *ed,NodeSpec **ns
12649 ,NodeData **nd,double *rdata,int *idata,double **gpost,double **npost)
12650 {
12651 int i777,i779;
12652 v[524]=nd[0]->X[0];
12653 v[525]=nd[0]->X[1];
12654 v[526]=nd[0]->X[2];
12655 v[527]=nd[1]->X[0];
12656 v[528]=nd[1]->X[1];
12657 v[529]=nd[1]->X[2];
12658 v[530]=nd[2]->X[0];
12659 v[531]=nd[2]->X[1];
12660 v[532]=nd[2]->X[2];
12661 v[533]=nd[3]->X[0];
12662 v[534]=nd[3]->X[1];
12663 v[535]=nd[3]->X[2];
12664 v[536]=nd[4]->X[0];
12665 v[537]=nd[4]->X[1];
12666 v[538]=nd[4]->X[2];
12667 v[539]=nd[5]->X[0];
12668 v[540]=nd[5]->X[1];
12669 v[541]=nd[5]->X[2];
12670 v[542]=nd[6]->X[0];
12671 v[543]=nd[6]->X[1];
12672 v[544]=nd[6]->X[2];
12673 v[545]=nd[7]->X[0];
12674 v[546]=nd[7]->X[1];
12675 v[547]=nd[7]->X[2];
12676 v[548]=nd[8]->X[0];
12677 v[549]=nd[8]->X[1];
12678 v[550]=nd[8]->X[2];
12679 v[551]=nd[9]->X[0];
12680 v[552]=nd[9]->X[1];
12681 v[553]=nd[9]->X[2];
12682 v[566]=nd[0]->at[0];
12683 v[567]=nd[0]->at[1];
12684 v[568]=nd[0]->at[2];
12685 v[569]=nd[1]->at[0];
12686 v[570]=nd[1]->at[1];
12687 v[571]=nd[1]->at[2];
12688 v[572]=nd[2]->at[0];
12689 v[573]=nd[2]->at[1];
12690 v[574]=nd[2]->at[2];
12691 v[575]=nd[3]->at[0];
12692 v[576]=nd[3]->at[1];
12693 v[577]=nd[3]->at[2];
12694 v[578]=nd[4]->at[0];
12695 v[579]=nd[4]->at[1];
12696 v[580]=nd[4]->at[2];
12697 v[581]=nd[5]->at[0];
12698 v[582]=nd[5]->at[1];
12699 v[583]=nd[5]->at[2];
12700 v[584]=nd[6]->at[0];
12701 v[585]=nd[6]->at[1];
12702 v[586]=nd[6]->at[2];
12703 v[587]=nd[7]->at[0];
12704 v[588]=nd[7]->at[1];
12705 v[589]=nd[7]->at[2];
12706 v[590]=nd[8]->at[0];
12707 v[591]=nd[8]->at[1];
12708 v[592]=nd[8]->at[2];
12709 v[593]=nd[9]->at[0];
12710 v[594]=nd[9]->at[1];
12711 v[595]=nd[9]->at[2];
12712 v[596]=nd[10]->at[0];
12713 v[597]=nd[11]->at[0];
12714 v[598]=nd[12]->at[0];
12715 v[599]=nd[13]->at[0];
12716 v[911]=v[598]-v[599];
12717 v[910]=v[597]-v[599];
12718 v[909]=v[596]-v[599];
12719 v[635]=es->Data[1];
12720 v[1031]=es->Data[0]/(1e0+v[635]);
12721 v[636]=(v[1031]*v[635])/(1e0-2e0*v[635]);
12722 v[638]=v[1031]/2e0;
12723 v[642]=es->Data[5];
12724 v[643]=es->Data[6];
12725 for(i777=1;i777<=es->id.NoIntPoints;i777++){
12726 i779=4*(-1+i777);
12727 v[778]=es->IntPoints[i779];
12728 v[809]=4e0*v[778];
12729 v[804]=-1e0+v[809];
12730 v[780]=es->IntPoints[1+i779];
12731 v[808]=4e0*v[780];
12732 v[856]=-(v[592]*v[808]);
12733 v[849]=-(v[591]*v[808]);
12734 v[842]=-(v[590]*v[808]);
12735 v[833]=-(v[550]*v[808]);
12736 v[826]=-(v[549]*v[808]);
12737 v[819]=-(v[548]*v[808]);
12738 v[805]=-1e0+v[808];
12739 v[781]=es->IntPoints[2+i779];
12740 v[810]=4e0*v[781];
12741 v[854]=-(v[595]*v[810]);
12742 v[847]=-(v[594]*v[810]);
12743 v[840]=-(v[593]*v[810]);
12744 v[831]=-(v[553]*v[810]);
12745 v[824]=-(v[552]*v[810]);
12746 v[817]=-(v[551]*v[810]);
12747 v[806]=-1e0+v[810];
12748 v[783]=v[778]*(-1e0+2e0*v[778]);
12749 v[784]=v[780]*(-1e0+2e0*v[780]);
12750 v[785]=v[781]*(-1e0+2e0*v[781]);
12751 v[786]=1e0-v[778]-v[780]-v[781];
12752 v[811]=-4e0*v[786];
12753 v[814]=-v[810]-v[811];
12754 v[813]=-v[808]-v[811];
12755 v[812]=-v[809]-v[811];
12756 v[807]=1e0+v[811];
12757 v[853]=v[577]*v[807];
12758 v[1032]=-(v[589]*v[809])+v[853];
12759 v[858]=v[1032]+v[574]*v[806]+v[583]*v[808]+v[586]*v[809]+v[595]*v[814]+v[856];
12760 v[855]=v[1032]+v[571]*v[805]+v[580]*v[809]+v[583]*v[810]+v[592]*v[813]+v[854];
12761 v[852]=v[568]*v[804]+v[580]*v[808]+v[586]*v[810]+v[589]*v[812]+v[853]+v[854]+v[856];
12762 v[846]=v[576]*v[807];
12763 v[1033]=-(v[588]*v[809])+v[846];
12764 v[851]=v[1033]+v[573]*v[806]+v[582]*v[808]+v[585]*v[809]+v[594]*v[814]+v[849];
12765 v[848]=v[1033]+v[570]*v[805]+v[579]*v[809]+v[582]*v[810]+v[591]*v[813]+v[847];
12766 v[845]=v[567]*v[804]+v[579]*v[808]+v[585]*v[810]+v[588]*v[812]+v[846]+v[847]+v[849];
12767 v[839]=v[575]*v[807];
12768 v[1034]=-(v[587]*v[809])+v[839];
12769 v[844]=v[1034]+v[572]*v[806]+v[581]*v[808]+v[584]*v[809]+v[593]*v[814]+v[842];
12770 v[841]=v[1034]+v[569]*v[805]+v[578]*v[809]+v[581]*v[810]+v[590]*v[813]+v[840];
12771 v[838]=v[566]*v[804]+v[578]*v[808]+v[584]*v[810]+v[587]*v[812]+v[839]+v[840]+v[842];
12772 v[830]=v[535]*v[807];
12773 v[1035]=-(v[547]*v[809])+v[830];
12774 v[835]=v[1035]+v[532]*v[806]+v[541]*v[808]+v[544]*v[809]+v[553]*v[814]+v[833];
12775 v[832]=v[1035]+v[529]*v[805]+v[538]*v[809]+v[541]*v[810]+v[550]*v[813]+v[831];
12776 v[829]=v[526]*v[804]+v[538]*v[808]+v[544]*v[810]+v[547]*v[812]+v[830]+v[831]+v[833];
12777 v[823]=v[534]*v[807];
12778 v[1036]=-(v[546]*v[809])+v[823];
12779 v[828]=v[1036]+v[531]*v[806]+v[540]*v[808]+v[543]*v[809]+v[552]*v[814]+v[826];
12780 v[825]=v[1036]+v[528]*v[805]+v[537]*v[809]+v[540]*v[810]+v[549]*v[813]+v[824];
12781 v[863]=-(v[828]*v[832])+v[825]*v[835];
12782 v[822]=v[525]*v[804]+v[537]*v[808]+v[543]*v[810]+v[546]*v[812]+v[823]+v[824]+v[826];
12783 v[865]=-(v[825]*v[829])+v[822]*v[832];
12784 v[864]=v[828]*v[829]-v[822]*v[835];
12785 v[816]=v[533]*v[807];
12786 v[1037]=-(v[545]*v[809])+v[816];
12787 v[821]=v[1037]+v[530]*v[806]+v[539]*v[808]+v[542]*v[809]+v[551]*v[814]+v[819];
12788 v[818]=v[1037]+v[527]*v[805]+v[536]*v[809]+v[539]*v[810]+v[548]*v[813]+v[817];
12789 v[871]=-(v[821]*v[825])+v[818]*v[828];
12790 v[867]=v[821]*v[832]-v[818]*v[835];
12791 v[815]=v[524]*v[804]+v[536]*v[808]+v[542]*v[810]+v[545]*v[812]+v[816]+v[817]+v[819];
12792 v[873]=-(v[818]*v[822])+v[815]*v[825];
12793 v[872]=v[821]*v[822]-v[815]*v[828];
12794 v[869]=v[818]*v[829]-v[815]*v[832];
12795 v[868]=-(v[821]*v[829])+v[815]*v[835];
12796 v[859]=v[815]*v[863]+v[818]*v[864]+v[821]*v[865];
12797 v[1048]=v[873]/v[859];
12798 v[1047]=v[872]/v[859];
12799 v[1046]=v[871]/v[859];
12800 v[1045]=v[869]/v[859];
12801 v[1044]=v[868]/v[859];
12802 v[1043]=v[867]/v[859];
12803 v[1042]=v[865]/v[859];
12804 v[1041]=v[864]/v[859];
12805 v[1040]=v[863]/v[859];
12806 v[787]=v[786]*(-1e0+2e0*v[786]);
12807 v[788]=4e0*v[778]*v[780];
12808 v[789]=4e0*v[780]*v[781];
12809 v[790]=4e0*v[778]*v[781];
12810 v[791]=4e0*v[778]*v[786];
12811 v[792]=4e0*v[780]*v[786];
12812 v[793]=4e0*v[781]*v[786];
12813 v[803]=v[596]*v[778]+v[597]*v[780]+v[598]*v[781]+v[599]*v[786];
12814 v[916]=(v[838]*v[863]+v[841]*v[864]+v[844]*v[865])/v[859];
12815 v[919]=(v[845]*v[867]+v[848]*v[868]+v[851]*v[869])/v[859];
12816 v[921]=(v[852]*v[871]+v[855]*v[872]+v[858]*v[873])/v[859];
12817 v[1038]=v[916]+v[919]+v[921];
12818 v[1039]=v[1038]*v[636]-v[803];
12819 v[1049]=-(v[643]/(1e0+(-1e0+v[1038])*v[642]));
12820 gpost[i777-1][0]=v[803];
12821 gpost[i777-1][1]=v[566]*v[783]+v[569]*v[784]+v[572]*v[785]+v[575]*v[787]+v[578]*v[788]
12822 +v[581]*v[789]+v[584]*v[790]+v[587]*v[791]+v[590]*v[792]+v[593]*v[793];
12823 gpost[i777-1][2]=v[567]*v[783]+v[570]*v[784]+v[573]*v[785]+v[576]*v[787]+v[579]*v[788]
12824 +v[582]*v[789]+v[585]*v[790]+v[588]*v[791]+v[591]*v[792]+v[594]*v[793];
12825 gpost[i777-1][3]=v[568]*v[783]+v[571]*v[784]+v[574]*v[785]+v[577]*v[787]+v[580]*v[788]
12826 +v[583]*v[789]+v[586]*v[790]+v[589]*v[791]+v[592]*v[792]+v[595]*v[793];
12827 gpost[i777-1][4]=v[1039]+v[1031]*v[916];
12828 gpost[i777-1][5]=v[1039]+2e0*v[638]*v[919];
12829 gpost[i777-1][6]=v[1039]+v[1031]*v[921];
12830 gpost[i777-1][7]=v[638]*(v[1043]*v[838]+v[1044]*v[841]+v[1045]*v[844]+v[1040]*v[845]
12831 +v[1041]*v[848]+v[1042]*v[851]);
12832 gpost[i777-1][8]=v[638]*(v[1046]*v[845]+v[1047]*v[848]+v[1048]*v[851]+v[1043]*v[852]
12833 +v[1044]*v[855]+v[1045]*v[858]);
12834 gpost[i777-1][9]=v[638]*(v[1046]*v[838]+v[1047]*v[841]+v[1048]*v[844]+v[1040]*v[852]
12835 +v[1041]*v[855]+v[1042]*v[858]);
12836 gpost[i777-1][10]=v[1049]*(v[1040]*v[909]+v[1041]*v[910]+v[1042]*v[911]);
12837 gpost[i777-1][11]=v[1049]*(v[1043]*v[909]+v[1044]*v[910]+v[1045]*v[911]);
12838 gpost[i777-1][12]=v[1049]*(v[1046]*v[909]+v[1047]*v[910]+v[1048]*v[911]);
12839 };/* end for */
12840};
12841}
12842#endif
void assemblyNonlinearSurfaceIntegralExternal(int dim, std::string FEType, MultiVectorPtr_Type f, MultiVectorPtr_Type d_rep, MatrixPtr_Type &Kext, std::vector< SC > &funcParameter, RhsFunc_Type func, ParameterListPtr_Type params, int FEloc=0)
assemblyNonlinearSurfaceIntegralExternal -
Definition FE_def.hpp:6809
void assemblyDivAndDivT(int dim, std::string FEType1, std::string FEType2, int degree, MatrixPtr_Type &Bmat, MatrixPtr_Type &BTmat, MapConstPtr_Type map1, MapConstPtr_Type map2, bool callFillComplete=true)
Assembly of \int q_h (nabla \cdot v_h) dx.
Definition FE_def.hpp:3776
void assemblyStress(int dim, std::string FEType, MatrixPtr_Type &A, CoeffFunc_Type func, int *parameters, bool callFillComplete=true)
(\grad u + (\grad u)^T, \grad v ); symmetrischer Gradient, wenn func = 1.0
Definition FE_def.hpp:4255
void assemblyAceDeformDiffuBlock(int dim, std::string FETypeChem, std::string FETypeSolid, int degree, int dofsChem, int dofsSolid, MultiVectorPtr_Type c_rep, MultiVectorPtr_Type d_rep, BlockMatrixPtr_Type &A, int blockRow, int blockCol, BlockMultiVectorPtr_Type &resVec, int block, ParameterListPtr_Type params, std::string assembleMode, bool callFillComplete=true, int FELocExternal=-1)
Definition FE_def.hpp:822
void assemblyNonLinearElasticity(int dim, std::string FEType, int degree, int dofs, MultiVectorPtr_Type d_rep, BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec, ParameterListPtr_Type params, bool callFillComplete=true, int FELocExternal=-1)
Assembly of Jacobian for nonlinear Elasticity.
Definition FE_def.hpp:449
void assemblyLinearElasticity(int dim, std::string FEType, int degree, int dofs, MultiVectorPtr_Type d_rep, BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec, ParameterListPtr_Type params, bool reAssemble, std::string assembleMode, bool callFillComplete=true, int FELocExternal=-1)
Assembly of Jacobian.
Definition FE_def.hpp:362
void assemblyBDStabilization(int dim, std::string FEType, MatrixPtr_Type &A, bool callFillComplete=true)
Definition FE_def.hpp:3999
void assemblyDivAndDivTFast(int dim, std::string FEType1, std::string FEType2, int degree, MatrixPtr_Type &Bmat, MatrixPtr_Type &BTmat, MapConstPtr_Type map1, MapConstPtr_Type map2, bool callFillComplete=true)
Assembly of \int q_h (nabla \cdot v_h) dx.
Definition FE_def.hpp:3906
void assemblyPressureMeanValue(int dim, std::string FEType, MatrixPtr_Type a, MatrixPtr_Type aT)
Assembling Pressure Integral to determine pressure mean value.
Definition FE_def.hpp:7273
void assemblyLaplaceXDim(int dim, std::string FEType, MatrixPtr_Type &A, CoeffFuncDbl_Type func, double *parameters, bool callFillComplete=true)
Definition FE_def.hpp:4073
void assemblyAdvectionVecField(int dim, std::string FEType, MatrixPtr_Type &A, MultiVectorPtr_Type u, bool callFillComplete)
Assembly of operator \int ((u_h \cdot \nabla ) v_h)v_h dx.
Definition FE_def.hpp:3591
void assemblyAdvectionInUVecField(int dim, std::string FEType, MatrixPtr_Type &A, MultiVectorPtr_Type u, bool callFillComplete)
Assembly of operator \int ((v_h \cdot \nabla ) u_h)v_h dx.
Definition FE_def.hpp:3685
void computeSteadyViscosityFE_CM(int dim, std::string FETypeVelocity, std::string FETypePressure, int dofsVelocity, int dofsPressure, MultiVectorPtr_Type u_rep, MultiVectorPtr_Type p_rep, ParameterListPtr_Type params)
Postprocessing: Using a converged velocity solution -> compute averaged viscosity inside an element a...
Definition FE_def.hpp:1253
void assemblyLinElasXDimE(int dim, std::string FEType, MatrixPtr_Type &A, MultiVectorPtr_Type eModVec, double nu, bool callFillComplete=true)
Same as assemblyLinElasXDim except for changing E Module Value.
Definition FE_def.hpp:4945
void assemblyNonlinearLaplace(int dim, std::string FEType, int degree, MultiVectorPtr_Type u_rep, BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec, ParameterListPtr_Type params, std::string assembleMode, bool callFillComplete=true, int FELocExternal=-1)
Assembly of Jacobian for nonlinear Laplace example.
Definition FE_def.hpp:2630
void assemblyAdditionalConvection(int dim, std::string FEType, MatrixPtr_Type &A, MultiVectorPtr_Type w, bool callFillComplete=true)
Addional Matrix due to ALE derivation: \int \rho_f div(w) u_h \cdot v_f dx, with mesh velocity w.
Definition FE_def.hpp:5257
void assemblyNavierStokes(int dim, std::string FETypeVelocity, std::string FETypePressure, int degree, int dofsVelocity, int dofsPressure, MultiVectorPtr_Type u_rep, MultiVectorPtr_Type p_rep, BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec, SmallMatrix_Type coeff, ParameterListPtr_Type params, bool reAssemble, std::string assembleMode, bool callFillComplete=true, int FELocExternal=-1)
Assembly of Jacobian for NavierStokes.
Definition FE_def.hpp:1078
void assemblyLaplaceAssFE(int dim, std::string FEType, int degree, int dofs, BlockMatrixPtr_Type &A, bool callFillComplete, int FELocExternal=-1)
Assembly of constant stiffness matix for laplacian operator .
Definition FE_def.hpp:1758
void assemblyLinElasXDim(int dim, std::string FEType, MatrixPtr_Type &A, double lambda, double mu, bool callFillComplete=true)
Definition FE_def.hpp:4589
void assemblyAceDeformDiffu(int dim, std::string FETypeChem, std::string FETypeSolid, int degree, int dofsChem, int dofsSolid, MultiVectorPtr_Type c_rep, MultiVectorPtr_Type d_rep, BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec, ParameterListPtr_Type params, std::string assembleMode, bool callFillComplete=true, int FELocExternal=-1)
Definition FE_def.hpp:644
Definition FiniteElement.hpp:17
static UN determineDegree(UN dim, std::string FEType, VarType orderOfDerivative)
Determine polynomial degree of a finite element basis function or its gradient that is required to se...
Definition Helper.cpp:68
@ Deriv0
order 0, f(x)
Definition Helper.hpp:27
@ Deriv1
order 1, gradient(f(x))
Definition Helper.hpp:28
static void buildTransformation(const vec_int_Type &element, vec2D_dbl_ptr_Type pointsRep, SmallMatrix< SC > &B, std::string FEType="P")
Build transformation of element to reference element depending on FEType.
Definition Helper.cpp:138
static int getPhi(vec2D_dbl_ptr_Type &Phi, vec_dbl_ptr_Type &weightsPhi, int dim, std::string FEType, int Degree, std::string FETypeQuadPoints="")
Get basisfunction phi per quadrature point.
Definition Helper.cpp:604
static int getDPhi(vec3D_dbl_ptr_Type &DPhi, vec_dbl_ptr_Type &weightsDPhi, int Dimension, std::string FEType, int Degree)
Full matrix representation of gradient of a basis function for each quadrature point.
Definition Helper.cpp:215
static void getQuadratureValues(int Dimension, int Degree, vec2D_dbl_ptr_Type &QuadPts, vec_dbl_ptr_Type &QuadW, std::string FEType)
Get quadrature formula.
Definition Helper.cpp:821
This class represents a templated small Matrix of type T. Primarily created for 2x2 and 3x3 matrices....
Definition SmallMatrix.hpp:22
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5
Definition sms.hpp:336
Definition sms.hpp:377
Definition sms.hpp:278
Definition sms.hpp:306