654 ParameterListPtr_Type params,
655 std::string assembleMode,
656 bool callFillComplete,
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." );
666 ElementsPtr_Type elementsChem= domainVec_.at(FElocChem)->getElementsC();
668 ElementsPtr_Type elementsSolid = domainVec_.at(FElocSolid)->getElementsC();
674 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocSolid)->getPointsRepeated();
676 MapConstPtr_Type mapChem = domainVec_.at(FElocChem)->getMapRepeated();
678 MapConstPtr_Type mapSolid = domainVec_.at(FElocSolid)->getMapRepeated();
680 vec_dbl_Type solution_c;
681 vec_dbl_Type solution_d;
683 vec_dbl_ptr_Type rhsVec;
688 if(FETypeChem ==
"P2"){
693 if(FETypeChem ==
"P2")
697 if(FETypeSolid ==
"P2")
702 if(FETypeSolid ==
"P2")
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);
711 tuple_disk_vec_ptr_Type problemDiskChem = Teuchos::rcp(
new tuple_disk_vec_Type(0));
712 problemDiskChem->push_back(chem);
714 std::string SCIModel = params->sublist(
"Parameter").get(
"Structure Model",
"SCI_simple");
716 if(assemblyFEElements_.size()== 0){
717 initAssembleFEElements(SCIModel,problemDisk,elementsChem, params,pointsRep,domainVec_.at(FElocSolid)->getElementMap());
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." );
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 ) );
727 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp(
new BlockMultiVector_Type( 2) );
728 resVecRep->addBlock(resVec_d,0);
729 resVecRep->addBlock(resVec_c,1);
733 SmallMatrix<SC> B(dim);
734 SmallMatrix<SC> Binv(dim);
737 for (UN T=0; T<assemblyFEElements_.size(); T++) {
738 vec_dbl_Type solution(0);
740 solution_c = getSolution(elementsChem->getElement(T).getVectorNodeList(), c_rep,dofsChem);
741 solution_d = getSolution(elementsSolid->getElement(T).getVectorNodeList(), d_rep,dofsSolid);
744 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
745 solution.insert( solution.end(), solution_c.begin(), solution_c.end() );
747 assemblyFEElements_[T]->updateSolution(solution);
749 SmallMatrixPtr_Type elementMatrix;
761 if(assembleMode ==
"Jacobian"){
762 assemblyFEElements_[T]->assembleJacobian();
764 elementMatrix = assemblyFEElements_[T]->getJacobian();
766 assemblyFEElements_[T]->advanceNewtonStep();
768 addFeBlockMatrix(A, elementMatrix, elementsSolid->getElement(T), elementsSolid->getElement(T), mapSolid, mapChem, problemDisk);
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);
779 if(assembleMode==
"MassMatrix"){
780 assemblyFEElements_[T]->assembleJacobian();
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);
785 addFeBlock(A, elementMatrix, elementsChem->getElement(T), mapChem, 0, 0, problemDiskChem);
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();
800 else if(assembleMode ==
"Rhs"){
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 ) );
805 resVecUnique_d->putScalar(0.);
806 resVecUnique_c->putScalar(0.);
808 resVecUnique_d->exportFromVector( resVec_d,
true,
"Add" );
809 resVecUnique_c->exportFromVector( resVec_c,
true,
"Add" );
811 resVec->addBlock(resVecUnique_d,0);
812 resVec->addBlock(resVecUnique_c,1);
814 else if(assembleMode ==
"MassMatrix"){
815 A->getBlock(0,0)->fillComplete();
821template <
class SC,
class LO,
class GO,
class NO>
823 std::string FETypeChem,
824 std::string FETypeSolid,
828 MultiVectorPtr_Type c_rep,
829 MultiVectorPtr_Type d_rep,
830 BlockMatrixPtr_Type &A,
833 BlockMultiVectorPtr_Type &resVec,
835 ParameterListPtr_Type params,
836 std::string assembleMode,
837 bool callFillComplete,
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" );
848 ElementsPtr_Type elementsChem= domainVec_.at(FElocSolid)->getElementsC();
850 ElementsPtr_Type elementsSolid = domainVec_.at(FElocSolid)->getElementsC();
856 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocSolid)->getPointsRepeated();
860 MapConstPtr_Type mapSolid = domainVec_.at(FElocSolid)->getMapRepeated();
862 vec_dbl_Type solution_c;
863 vec_dbl_Type solution_d;
865 vec_dbl_ptr_Type rhsVec;
870 if(FETypeChem ==
"P2"){
875 if(FETypeChem ==
"P2")
879 if(FETypeSolid ==
"P2")
884 if(FETypeSolid ==
"P2")
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);
893 std::string SCIModel = params->sublist(
"Parameter").get(
"Structure Model",
"SCI_simple");
895 if(assemblyFEElements_.size()== 0){
896 initAssembleFEElements(SCIModel,problemDisk,elementsChem, params,pointsRep,domainVec_.at(FElocSolid)->getElementMap());
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." );
904 MultiVectorPtr_Type resVec_d = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldRepeated(), 1 ) );
906 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp(
new BlockMultiVector_Type( 1) );
907 resVecRep->addBlock(resVec_d,0);
910 for (UN T=0; T<assemblyFEElements_.size(); T++) {
911 vec_dbl_Type solution(0);
913 solution_c = getSolution(elementsChem->getElement(T).getVectorNodeList(), c_rep,dofsChem);
914 solution_d = getSolution(elementsSolid->getElement(T).getVectorNodeList(), d_rep,dofsSolid);
917 solution.insert( solution.end(), solution_d.begin(), solution_d.end() );
918 solution.insert( solution.end(), solution_c.begin(), solution_c.end() );
920 assemblyFEElements_[T]->updateSolution(solution);
922 SmallMatrixPtr_Type elementMatrix;
924 if(assembleMode ==
"Jacobian"){
925 assemblyFEElements_[T]->assembleJacobian();
927 elementMatrix = assemblyFEElements_[T]->getJacobian();
929 assemblyFEElements_[T]->advanceNewtonStep();
930 addFeBlock(A, elementMatrix, elementsSolid->getElement(T), mapSolid, 0, 0, problemDisk);
933 if(assembleMode ==
"Rhs"){
934 assemblyFEElements_[T]->assembleRHS();
935 rhsVec = assemblyFEElements_[T]->getRHS();
936 addFeBlockMv(resVecRep, rhsVec, elementsSolid->getElement(T), dofsSolid);
945 if ( assembleMode !=
"Rhs"){
946 A->getBlock(0,0)->fillComplete();
952 if(assembleMode ==
"Rhs"){
954 MultiVectorPtr_Type resVecUnique_d = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FElocSolid)->getMapVecFieldUnique(), 1 ) );
957 resVecUnique_d->putScalar(0.);
960 resVecUnique_d->exportFromVector( resVec_d,
true,
"Add" );
963 resVec->addBlock(resVecUnique_d,0);
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){
984 int numDisk = problemDisk->size();
986 int dofs1 = std::get<2>(problemDisk->at(0));
987 int dofs2 = std::get<2>(problemDisk->at(1));
989 int numNodes1 = std::get<3>(problemDisk->at(0));
990 int numNodes2=std::get<3>(problemDisk->at(1));
992 int dofsBlock1 = dofs1*numNodes1;
993 int dofsBlock2 = dofs2*numNodes2;
995 Teuchos::Array<SC> value1( numNodes1, 0. );
996 Teuchos::Array<GO> columnIndices1( numNodes1, 0 );
998 Teuchos::Array<SC> value2( numNodes2, 0. );
999 Teuchos::Array<GO> columnIndices2( numNodes2, 0 );
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];
1009 A->getBlock(0,0)->insertGlobalValues( row, columnIndices1(), value1() );
1013 int offset= numNodes1*dofs1;
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() );
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);
1043 A->getBlock(0,1)->insertGlobalValues( row, columnIndices2(), value2() );
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);
1056 A->getBlock(1,0)->insertGlobalValues( row, columnIndices1(), value1() );
1077template <
class SC,
class LO,
class GO,
class NO>
1079 std::string FETypeVelocity,
1080 std::string FETypePressure,
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,
1091 std::string assembleMode,
1092 bool callFillComplete,
1096 UN FElocVel = checkFE(dim,FETypeVelocity);
1097 UN FElocPres = checkFE(dim,FETypePressure);
1099 ElementsPtr_Type elements = domainVec_.at(FElocVel)->getElementsC();
1101 ElementsPtr_Type elementsPres = domainVec_.at(FElocPres)->getElementsC();
1103 int dofsElement = elements->getElement(0).getVectorNodeList().size();
1105 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FElocVel)->getPointsRepeated();
1107 MapConstPtr_Type mapVel = domainVec_.at(FElocVel)->getMapRepeated();
1109 MapConstPtr_Type mapPres = domainVec_.at(FElocPres)->getMapRepeated();
1111 vec_dbl_Type solution(0);
1112 vec_dbl_Type solution_u;
1113 vec_dbl_Type solution_p;
1115 vec_dbl_ptr_Type rhsVec;
1120 if(FETypeVelocity ==
"P2")
1125 if(FETypeVelocity ==
"P2")
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);
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());
1138 initAssembleFEElements(
"NavierStokes",problemDisk,elements, params,pointsRep,domainVec_.at(FElocVel)->getElementMap());
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." );
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 ) );
1148 BlockMultiVectorPtr_Type resVecRep = Teuchos::rcp(
new BlockMultiVector_Type( 2) );
1149 resVecRep->addBlock(resVec_u,0);
1150 resVecRep->addBlock(resVec_p,1);
1153 for (UN T=0; T<assemblyFEElements_.size(); T++) {
1154 vec_dbl_Type solution(0);
1156 solution_u = getSolution(elements->getElement(T).getVectorNodeList(), u_rep,dofsVelocity);
1157 solution_p = getSolution(elementsPres->getElement(T).getVectorNodeList(), p_rep,dofsPressure);
1159 solution.insert( solution.end(), solution_u.begin(), solution_u.end() );
1160 solution.insert( solution.end(), solution_p.begin(), solution_p.end() );
1162 assemblyFEElements_[T]->updateSolution(solution);
1164 SmallMatrixPtr_Type elementMatrix;
1166 if(assembleMode ==
"Jacobian"){
1167 assemblyFEElements_[T]->assembleJacobian();
1169 elementMatrix = assemblyFEElements_[T]->getJacobian();
1171 assemblyFEElements_[T]->advanceNewtonStep();
1174 addFeBlock(A, elementMatrix, elements->getElement(T), mapVel, 0, 0, problemDisk);
1176 addFeBlockMatrix(A, elementMatrix, elements->getElement(T), elementsPres->getElement(T), mapVel, mapPres, problemDisk);
1178 if(assembleMode ==
"FixedPoint"){
1182 if(params->sublist(
"Material").get(
"Newtonian",
true) ==
false)
1184 AssembleFEGeneralizedNewtonianPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFEGeneralizedNewtonian_Type>( assemblyFEElements_[T] );
1185 elTmp->assembleFixedPoint();
1186 elementMatrix = elTmp->getFixedPointMatrix();
1190 AssembleFENavierStokesPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFENavierStokes_Type>( assemblyFEElements_[T] );
1191 elTmp->assembleFixedPoint();
1192 elementMatrix = elTmp->getFixedPointMatrix();
1196 assemblyFEElements_[T]->advanceNewtonStep();
1199 addFeBlock(A, elementMatrix, elements->getElement(T), mapVel, 0, 0, problemDisk);
1201 addFeBlockMatrix(A, elementMatrix, elements->getElement(T), elementsPres->getElement(T),mapVel, mapPres, problemDisk);
1204 if(assembleMode ==
"Rhs"){
1205 AssembleFENavierStokesPtr_Type elTmp = Teuchos::rcp_dynamic_cast<AssembleFENavierStokes_Type>(assemblyFEElements_[T] );
1206 elTmp->setCoeff(coeff);
1207 assemblyFEElements_[T]->assembleRHS();
1208 rhsVec = assemblyFEElements_[T]->getRHS();
1209 addFeBlockMv(resVecRep, rhsVec, elements->getElement(T),elementsPres->getElement(T), dofsVelocity,dofsPressure);
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());
1222 if(assembleMode ==
"Rhs"){
1224 MultiVectorPtr_Type resVecUnique_u = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FElocVel)->getMapVecFieldUnique(), 1 ) );
1225 MultiVectorPtr_Type resVecUnique_p = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FElocPres)->getMapUnique(), 1 ) );
1227 resVecUnique_u->putScalar(0.);
1228 resVecUnique_p->putScalar(0.);
1230 resVecUnique_u->exportFromVector( resVec_u,
true,
"Add" );
1231 resVecUnique_p->exportFromVector( resVec_p,
true,
"Add" );
1233 resVec->addBlock(resVecUnique_u,0);
1234 resVec->addBlock(resVecUnique_p,1);
1245template <
class SC,
class LO,
class GO,
class NO>
1248 for (UN T=0; T<assemblyFEElements_.size(); T++)
1250 assemblyFEElements_[T]->changeLinearization(linearization);
1265template <
class SC,
class LO,
class GO,
class NO>
1267 std::string FETypeVelocity,
1268 std::string FETypePressure,
1271 MultiVectorPtr_Type u_rep,
1272 MultiVectorPtr_Type p_rep,
1273 ParameterListPtr_Type params){
1276 UN FElocVel = checkFE(dim,FETypeVelocity);
1277 UN FElocPres = checkFE(dim,FETypePressure);
1279 ElementsPtr_Type elements = domainVec_.at(FElocVel)->getElementsC();
1280 ElementsPtr_Type elementsPres = domainVec_.at(FElocPres)->getElementsC();
1282 vec_dbl_Type solution(0);
1283 vec_dbl_Type solution_u;
1284 vec_dbl_Type solution_p;
1285 vec_dbl_Type solution_viscosity;
1288 MultiVectorPtr_Type Sol_viscosity = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FElocVel)->getElementMap(), 1 ) );
1289 BlockMultiVectorPtr_Type visco_output = Teuchos::rcp(
new BlockMultiVector_Type(1) );
1290 visco_output->addBlock(Sol_viscosity,0);
1293 for (UN T=0; T<assemblyFEElements_.size(); T++) {
1295 vec_dbl_Type solution(0);
1296 solution_u = getSolution(elements->getElement(T).getVectorNodeList(), u_rep,dofsVelocity);
1297 solution_p = getSolution(elementsPres->getElement(T).getVectorNodeList(), p_rep,dofsPressure);
1299 solution.insert( solution.end(), solution_u.begin(), solution_u.end() );
1300 solution.insert( solution.end(), solution_p.begin(), solution_p.end() );
1302 assemblyFEElements_[T]->updateSolution(solution);
1304 assemblyFEElements_[T]->computeLocalconstOutputField();
1305 solution_viscosity = assemblyFEElements_[T]->getLocalconstOutputField();
1307 Teuchos::ArrayRCP<SC> resArray_block = visco_output->getBlockNonConst(0)->getDataNonConst(0);
1308 resArray_block[T] = solution_viscosity[0];
1312 this->const_output_fields= visco_output;
1330template <
class SC,
class LO,
class GO,
class NO>
1331void FE<SC,LO,GO,NO>::addFeBlockMv(BlockMultiVectorPtr_Type &res, vec_dbl_ptr_Type rhsVec,
FiniteElement elementBlock1,
FiniteElement elementBlock2,
int dofs1,
int dofs2 ){
1333 Teuchos::ArrayRCP<SC> resArray_block1 = res->getBlockNonConst(0)->getDataNonConst(0);
1335 Teuchos::ArrayRCP<SC> resArray_block2 = res->getBlockNonConst(1)->getDataNonConst(0);
1337 vec_LO_Type nodeList_block1 = elementBlock1.getVectorNodeList();
1339 vec_LO_Type nodeList_block2 = elementBlock2.getVectorNodeList();
1341 for(
int i=0; i< nodeList_block1.size() ; i++){
1342 for(
int d=0; d<dofs1; d++){
1343 resArray_block1[nodeList_block1[i]*dofs1+d] += (*rhsVec)[i*dofs1+d];
1346 int offset = nodeList_block1.size()*dofs1;
1348 for(
int i=0; i < nodeList_block2.size(); i++){
1349 for(
int d=0; d<dofs2; d++)
1350 resArray_block2[nodeList_block2[i]*dofs2+d] += (*rhsVec)[i*dofs2+d+offset];
1368template <
class SC,
class LO,
class GO,
class NO>
1369void 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){
1371 int dofs1 = std::get<2>(problemDisk->at(row));
1373 int numNodes1 = std::get<3>(problemDisk->at(row));
1375 int dofsBlock1 = dofs1*numNodes1;
1377 Teuchos::Array<SC> value( numNodes1, 0. );
1378 Teuchos::Array<GO> columnIndices( numNodes1, 0 );
1380 for (UN i=0; i < numNodes1 ; i++) {
1381 for(
int di=0; di<dofs1; di++){
1382 GO rowID =GO (dofs1* mapRow->getGlobalElement( element.getNode(i) )+di);
1383 for(
int d=0; d<dofs1; d++){
1384 for (UN j=0; j < columnIndices.size(); j++){
1385 columnIndices[j] = GO ( dofs1 * mapRow->getGlobalElement( element.getNode(j) ) + d );
1386 value[j] = (*elementMatrix)[dofs1*i+di][dofs1*j+d];
1388 A->getBlock(row,column)->insertGlobalValues( rowID, columnIndices(), value() );
1404template <
class SC,
class LO,
class GO,
class NO>
1405void 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){
1407 vec2D_dbl_Type nodes;
1408 for (UN T=0; T<elements->numberElements(); T++) {
1410 nodes = getCoordinates(elements->getElement(T).getVectorNodeList(), pointsRep);
1412 AssembleFEFactory<SC,LO,GO,NO> assembleFEFactory;
1414 AssembleFEPtr_Type assemblyFE = assembleFEFactory.build(elementType,elements->getElement(T).getFlag(),nodes, params,problemDisk);
1416 assemblyFE->setGlobalElementID(elementMap->getGlobalElement(T));
1418 assemblyFEElements_.push_back(assemblyFE);
1434template <
class SC,
class LO,
class GO,
class NO>
1435vec2D_dbl_Type FE<SC,LO,GO,NO>::getCoordinates(vec_LO_Type localIDs, vec2D_dbl_ptr_Type points){
1437 vec2D_dbl_Type coordinates(0,vec_dbl_Type( points->at(0).size()));
1438 for(
int i=0; i < localIDs.size() ; i++){
1439 coordinates.push_back(points->at(localIDs[i]));
1455template <
class SC,
class LO,
class GO,
class NO>
1456vec_dbl_Type FE<SC,LO,GO,NO>::getSolution(vec_LO_Type localIDs, MultiVectorPtr_Type u_rep,
int dofsVelocity){
1458 Teuchos::ArrayRCP<SC> uArray = u_rep->getDataNonConst(0);
1460 vec_dbl_Type solution(0);
1461 for(
int i=0; i < localIDs.size() ; i++){
1462 for(
int d=0; d<dofsVelocity; d++)
1463 solution.push_back(uArray[localIDs[i]*dofsVelocity+d]);
1470template <
class SC,
class LO,
class GO,
class NO>
1471void FE<SC,LO,GO,NO>::applyBTinv( vec3D_dbl_ptr_Type& dPhiIn,
1472 vec3D_dbl_Type& dPhiOut,
1473 const SmallMatrix<SC>& Binv){
1474 UN dim = Binv.size();
1475 for (UN w=0; w<dPhiIn->size(); w++){
1476 for (UN i=0; i < dPhiIn->at(w).size(); i++) {
1477 for (UN d1=0; d1<dim; d1++) {
1478 for (UN d2=0; d2<dim; d2++) {
1479 dPhiOut[w][i][d1] += dPhiIn->at(w).at(i).at(d2) * Binv[d2][d1];
1486template <
class SC,
class LO,
class GO,
class NO>
1487void FE<SC,LO,GO,NO>::assemblyEmptyMatrix(MatrixPtr_Type &A){
1490template <
class SC,
class LO,
class GO,
class NO>
1491void FE<SC,LO,GO,NO>::assemblyIdentity(MatrixPtr_Type &A){
1492 Teuchos::Array<SC> value(1, Teuchos::ScalarTraits<SC>::one() );
1493 Teuchos::Array<GO> index(1);
1494 MapConstPtr_Type map = A->getMap();
1495 for (
int i=0; i<A->getNodeNumRows(); i++) {
1496 index[0] = map->getGlobalElement( i );
1497 A->insertGlobalValues( index[0], index(), value() );
1503template <
class SC,
class LO,
class GO,
class NO>
1504void FE<SC,LO,GO,NO>::assemblySurfaceRobinBC(
int dim,
1505 std::string FETypeP,
1506 std::string FETypeV,
1507 MultiVectorPtr_Type u,
1509 std::vector<SC>& funcParameter,
1511 ParameterListPtr_Type parameters){
1513 ElementsPtr_Type elements = domainVec_.at(1)->getElementsC();
1514 ElementsPtr_Type elementsV = domainVec_.at(0)->getElementsC();
1516 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(1)->getPointsRepeated();
1518 MapConstPtr_Type map = domainVec_.at(1)->getMapRepeated();
1520 vec2D_dbl_ptr_Type phi,phiV;
1521 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
1524 UN extraDeg = Helper::determineDegree( dim-1, FETypeV, Helper::Deriv0);
1525 UN deg = Helper::determineDegree( dim-1, FETypeP, Helper::Deriv0)*2 + extraDeg;
1528 Helper::getPhi(phi, weights, dim-1, FETypeP, deg);
1529 Helper::getPhi(phiV, weights, dim-1, FETypeV, deg);
1533 SmallMatrix<SC> B(dim);
1536 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
1537 vec_dbl_Type uLocN( weights->size() , -1. );
1539 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
1543 vec_dbl_Type b(dim);
1545 std::vector<double> valueFunc(dim);
1547 SC* paramsFunc = &(funcParameter[0]);
1548 for (UN T=0; T<elements->numberElements(); T++) {
1549 FiniteElement fe = elementsV->getElement( T );
1550 ElementsPtr_Type subEl = fe.getSubElements();
1551 for (
int surface=0; surface<fe.numSubElements(); surface++) {
1552 FiniteElement feSub = subEl->getElement( surface );
1553 if(subEl->getDimension() == dim-1){
1556 vec_int_Type nodeList = feSub.getVectorNodeListNonConst();
1557 vec_int_Type nodeListP = elements->getElement(T).getSubElements()->getElement(surface).getVectorNodeListNonConst();
1559 vec_dbl_Type v_E(dim,1.);
1561 vec_dbl_Type x(dim,0.);
1562 paramsFunc[ funcParameter.size() - 1 ] = feSub.getFlag();
1564 func( &x[0], &valueFunc[0], paramsFunc);
1565 if(valueFunc[0] > 0.){
1566 Helper::computeSurfaceNormal(dim, pointsRep,nodeListP,v_E,norm_v_E);
1568 Helper::buildTransformationSurface( nodeListP, pointsRep, B, b, FETypeP);
1570 elScaling = B.computeScaling( );
1571 for (
int w=0; w<phiV->size(); w++){
1572 for (
int d=0; d<dim; d++) {
1574 for (
int i=0; i < phiV->at(0).size(); i++) {
1575 LO index = dim * nodeList[i] + d;
1576 uLoc[d][w] += uArray[index] * phiV->at(w).at(i);
1580 for (
int w=0; w<phiV->size(); w++){
1582 for (
int d=0; d<dim; d++) {
1583 uLocN[w] += uLoc[d][w] *v_E[d] / norm_v_E;
1586 for (UN i=0; i < phi->at(0).size(); i++) {
1587 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
1588 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
1589 for (UN j=0; j < value.size(); j++) {
1590 for (UN w=0; w<phi->size(); w++) {
1591 value[j] += weights->at(w) * uLocN[w]* (*phi)[w][j] * (*phi)[w][i] ;
1593 value[j] *= elScaling;
1594 indices[j] = GO ( map->getGlobalElement( nodeListP[j] ) );
1597 GO row = GO ( map->getGlobalElement( nodeListP[i] ) );
1598 A->insertGlobalValues( row, indices(), value() );
1876template <
class SC,
class LO,
class GO,
class NO>
1881 BlockMatrixPtr_Type &A,
1882 bool callFillComplete,
1884 ParameterListPtr_Type params = Teuchos::getParametersFromXmlFile(
"parametersProblemLaplace.xml");
1886 UN FEloc = checkFE(dim,FEType);
1887 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1888 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1889 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1890 vec2D_dbl_Type nodes;
1897 tuple_disk_vec_ptr_Type problemDisk = Teuchos::rcp(
new tuple_disk_vec_Type(0));
1898 tuple_ssii_Type vel (
"Laplace",FEType,dofs,numNodes);
1899 problemDisk->push_back(vel);
1900 if(assemblyFEElements_.size()== 0)
1901 initAssembleFEElements(
"Laplace",problemDisk,elements, params,pointsRep,domainVec_.at(0)->getElementMap());
1902 else if(assemblyFEElements_.size() != elements->numberElements())
1903 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Number Elements not the same as number assembleFE elements." );
1904 for (UN T=0; T<elements->numberElements(); T++) {
1905 assemblyFEElements_[T]->assembleJacobian();
1906 SmallMatrixPtr_Type elementMatrix = assemblyFEElements_[T]->getJacobian();
1907 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0, problemDisk);
1910 if(callFillComplete)
1911 A->getBlock(0,0)->fillComplete();
1915template <
class SC,
class LO,
class GO,
class NO>
1916void FE<SC,LO,GO,NO>::assemblyLaplaceDiffusion(
int dim,
1920 vec2D_dbl_Type diffusionTensor,
1921 bool callFillComplete,
1923 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
1925 if (FELocExternal<0)
1926 FEloc = checkFE(dim,FEType);
1928 FEloc = FELocExternal;
1930 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
1932 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
1934 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
1936 vec3D_dbl_ptr_Type dPhi;
1937 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
1949 vec_dbl_Type v_i(dim);
1950 vec_dbl_Type v_j(dim);
1955 if(diffusionTensor.size()==0 || diffusionTensor.size() < dim ){
1956 vec2D_dbl_Type diffusionTensor(3,vec_dbl_Type(3,0));
1957 for(
int i=0; i< dim; i++){
1958 diffusionTensor[i][i]=1.;
1962 for(
int i=0; i< dim; i++){
1963 for(
int j=0; j<dim; j++){
1964 diffusionT[i][j]=diffusionTensor[i][j];
1969 for (UN T=0; T<elements->numberElements(); T++) {
1971 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
1972 detB = B.computeInverse(Binv);
1973 absDetB = std::fabs(detB);
1975 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
1976 applyBTinv( dPhi, dPhiTrans, Binv );
1978 vec3D_dbl_Type dPhiTransDiff( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
1979 applyDiff( dPhiTrans, dPhiTransDiff, diffusionT );
1981 for (UN i=0; i < dPhiTrans[0].size(); i++) {
1982 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
1983 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
1985 for (UN j=0; j < value.size(); j++) {
1986 for (UN w=0; w<dPhiTrans.size(); w++) {
1987 for (UN d=0; d<dim; d++){
1988 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTransDiff[w][j][d];
1991 value[j] *= absDetB;
1992 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
1993 if (setZeros_ && std::fabs(value[j]) < myeps_) {
1997 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
1999 A->insertGlobalValues( row, indices(), value() );
2004 if (callFillComplete)
2009template <
class SC,
class LO,
class GO,
class NO>
2010void FE<SC,LO,GO,NO>::applyDiff( vec3D_dbl_Type& dPhiIn,
2011 vec3D_dbl_Type& dPhiOut,
2012 SmallMatrix<SC>& diffT){
2013 UN dim = diffT.size();
2014 for (UN w=0; w<dPhiIn.size(); w++){
2015 for (UN i=0; i < dPhiIn[w].size(); i++) {
2016 for (UN d1=0; d1<dim; d1++) {
2017 for (UN d2=0; d2<dim; d2++) {
2018 dPhiOut[w][i][d1] += dPhiIn[w][i][d2]* diffT[d2][d1];
2348template <
class SC,
class LO,
class GO,
class NO>
2349void FE<SC,LO,GO,NO>::assemblyMass(
int dim,
2351 std::string fieldType,
2353 bool callFillComplete){
2355 TEUCHOS_TEST_FOR_EXCEPTION( FEType ==
"P0", std::logic_error,
"Not implemented for P0" );
2356 UN FEloc = checkFE(dim,FEType);
2357 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2359 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2361 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2363 vec2D_dbl_ptr_Type phi;
2364 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2367 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv0);
2369 Helper::getPhi( phi, weights, dim, FEType, deg );
2373 SmallMatrix<SC> B(dim);
2375 vec_dbl_Type v_i(dim);
2376 vec_dbl_Type v_j(dim);
2378 for (UN T=0; T<elements->numberElements(); T++) {
2380 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType);
2381 detB = B.computeDet( );
2382 absDetB = std::fabs(detB);
2384 for (UN i=0; i < phi->at(0).size(); i++) {
2385 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
2386 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
2387 for (UN j=0; j < value.size(); j++) {
2388 for (UN w=0; w<phi->size(); w++) {
2389 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
2392 value[j] *= absDetB;
2393 if (!fieldType.compare(
"Scalar")) {
2394 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2398 if (!fieldType.compare(
"Scalar")) {
2399 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2400 A->insertGlobalValues( row, indices(), value() );
2402 else if (!fieldType.compare(
"Vector")) {
2403 for (UN d=0; d<dim; d++) {
2404 for (
int j=0; j<indices.size(); j++) {
2405 indices[j] = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2407 GO row = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2408 A->insertGlobalValues( row, indices(), value() );
2412 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Specify valid vieldType for assembly of mass matrix.");
2417 if (callFillComplete)
2425template <
class SC,
class LO,
class GO,
class NO>
2426void FE<SC,LO,GO,NO>::assemblyMass(
int dim,
2428 std::string fieldType,
2431 bool callFillComplete){
2433 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
2435 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2437 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2439 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2441 vec2D_dbl_ptr_Type phi;
2442 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2445 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv0);
2447 Helper::getPhi( phi, weights, dim, FEType, deg );
2451 SmallMatrix<SC> B(dim);
2453 vec_dbl_Type v_i(dim);
2454 vec_dbl_Type v_j(dim);
2456 for (UN T=0; T<elements->numberElements(); T++) {
2458 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType);
2459 detB = B.computeDet( );
2460 absDetB = std::fabs(detB);
2462 for (UN i=0; i < phi->at(0).size(); i++) {
2463 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
2464 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
2465 for (UN j=0; j < value.size(); j++) {
2466 for (UN w=0; w<phi->size(); w++) {
2467 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
2469 value[j] *= absDetB;
2470 if (!fieldType.compare(
"Scalar")) {
2471 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2475 if (!fieldType.compare(
"Scalar")) {
2476 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2477 A->insertGlobalValues( row, indices(), value() );
2479 else if (!fieldType.compare(
"Vector")) {
2480 for (UN d=0; d<dim; d++) {
2481 for (
int j=0; j<indices.size(); j++) {
2482 indices[j] = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2484 GO row = (GO) ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2485 A->insertGlobalValues( row, indices(), value() );
2489 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Specify valid vieldType for assembly of mass matrix.");
2494 if (callFillComplete)
2499template <
class SC,
class LO,
class GO,
class NO>
2500void FE<SC,LO,GO,NO>::assemblyLaplace(
int dim,
2504 bool callFillComplete,
2506 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
2508 if (FELocExternal<0)
2509 FEloc = checkFE(dim,FEType);
2511 FEloc = FELocExternal;
2513 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2515 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2517 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2519 vec3D_dbl_ptr_Type dPhi;
2520 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2522 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2523 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2527 SmallMatrix<SC> B(dim);
2528 SmallMatrix<SC> Binv(dim);
2530 vec_dbl_Type v_i(dim);
2531 vec_dbl_Type v_j(dim);
2533 for (UN T=0; T<elements->numberElements(); T++) {
2535 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
2536 detB = B.computeInverse(Binv);
2537 absDetB = std::fabs(detB);
2539 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
2540 applyBTinv( dPhi, dPhiTrans, Binv );
2541 for (UN i=0; i < dPhiTrans[0].size(); i++) {
2542 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
2543 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
2544 for (UN j=0; j < value.size(); j++) {
2545 for (UN w=0; w<dPhiTrans.size(); w++) {
2546 for (UN d=0; d<dim; d++){
2547 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTrans[w][j][d];
2550 value[j] *= absDetB;
2551 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
2553 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
2555 A->insertGlobalValues( row, indices(), value() );
2560 if (callFillComplete)
2565template <
class SC,
class LO,
class GO,
class NO>
2566void FE<SC,LO,GO,NO>::assemblyLaplaceVecField(
int dim,
2570 bool callFillComplete){
2572 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P1-disc" || FEType ==
"P0",std::logic_error,
"Not implemented for P0 or P1-disc");
2573 UN FEloc = checkFE(dim,FEType);
2575 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2577 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2579 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2581 vec3D_dbl_ptr_Type dPhi;
2582 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2584 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2586 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2590 SmallMatrix<SC> B(dim);
2591 SmallMatrix<SC> Binv(dim);
2593 vec_dbl_Type v_i(dim);
2594 vec_dbl_Type v_j(dim);
2597 for (UN T=0; T<elements->numberElements(); T++) {
2599 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
2600 detB = B.computeInverse(Binv);
2601 absDetB = std::fabs(detB);
2603 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
2604 applyBTinv( dPhi, dPhiTrans, Binv );
2606 for (UN i=0; i < dPhiTrans[0].size(); i++) {
2607 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
2608 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
2609 for (UN j=0; j < value.size(); j++) {
2610 for (UN w=0; w<dPhiTrans.size(); w++) {
2611 for (UN d=0; d<dim; d++)
2612 value[j] += weights->at(w) * dPhiTrans[w][i][d] * dPhiTrans[w][j][d];
2614 value[j] *= absDetB;
2615 if (setZeros_ && std::fabs(value[j]) < myeps_) {
2619 for (UN d=0; d<dim; d++) {
2620 for (UN j=0; j < indices.size(); j++)
2621 indices[j] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2623 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2624 A->insertGlobalValues( row, indices(), value() );
2628 if (callFillComplete)
2632template <
class SC,
class LO,
class GO,
class NO>
2633void FE<SC,LO,GO,NO>::assemblyLaplaceVecFieldV2(
int dim,
2637 bool callFillComplete){
2639 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
2640 UN FEloc = checkFE(dim,FEType);
2642 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2644 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2646 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2648 vec3D_dbl_ptr_Type dPhi;
2649 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2651 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
2653 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
2655 Teuchos::BLAS<int, SC> teuchosBLAS;
2657 int nmbQuadPoints = dPhi->size();
2658 int nmbScalarDPhi = dPhi->at(0).size();
2659 int nmbAllDPhi = nmbScalarDPhi * dim;
2660 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
2661 int sizeLocStiff = dim*dim;
2662 Teuchos::Array<SmallMatrix<double> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<double>(dim) );
2663 this->buildFullDPhi( dPhi, dPhiMat );
2668 SmallMatrix<SC> B(dim);
2669 SmallMatrix<SC> Binv(dim);
2671 vec_dbl_Type v_i(dim);
2672 vec_dbl_Type v_j(dim);
2674 for (UN T=0; T<elements->numberElements(); T++) {
2676 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType);
2677 detB = B.computeInverse(Binv);
2678 absDetB = std::fabs(detB);
2680 Teuchos::Array<SmallMatrix<double> > allDPhiMatTrans( dPhiMat.size(), SmallMatrix<double>() );
2682 for (
int i=0; i<allDPhiMatTrans.size(); i++) {
2683 SmallMatrix<double> res = dPhiMat[i] * Binv;
2684 allDPhiMatTrans[i] = res;
2687 SmallMatrix<double> locStiffMat( nmbAllDPhi, 0. );
2689 for (
int p=0; p<nmbQuadPoints; p++){
2691 double* allDPhiBlas =
new double[ nmbAllDPhi * sizeLocStiff ];
2693 int offset = p * nmbAllDPhi;
2694 int offsetInArray = 0;
2695 for (
int i=0; i<nmbAllDPhi; i++) {
2696 fillMatrixArray( allDPhiMatTrans[ offset + i ], allDPhiBlas,
"rows",offsetInArray );
2697 offsetInArray += sizeLocStiff;
2700 double* locStiffMatBlas =
new double[ nmbAllDPhi * nmbAllDPhi ];
2702 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
2704 for (
int i=0; i<nmbAllDPhi; i++) {
2705 for (
int j=0; j<nmbAllDPhi; j++) {
2706 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
2710 delete [] allDPhiBlas;
2711 delete [] locStiffMatBlas;
2715 for (UN i=0; i < nmbScalarDPhi; i++) {
2716 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
2717 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
2718 for (UN d=0; d<dim; d++) {
2719 for (UN j=0; j < nmbScalarDPhi; j++){
2720 value[ j * dim + d ] = absDetB * locStiffMat[dim * i + d][j];
2721 indices[ j * dim + d ] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
2723 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
2724 A->insertGlobalValues( row, indices(), value() );
2728 if (callFillComplete)
2748template <
class SC,
class LO,
class GO,
class NO>
2750 int dim, std::string FEType,
int degree, MultiVectorPtr_Type u_rep,
2751 BlockMatrixPtr_Type &A, BlockMultiVectorPtr_Type &resVec,
2752 ParameterListPtr_Type params, std::string assembleMode,
bool callFillComplete,
2753 int FELocExternal) {
2755 ElementsPtr_Type elements = this->domainVec_.at(0)->getElementsC();
2760 vec2D_dbl_ptr_Type pointsRep = this->domainVec_.at(0)->getPointsRepeated();
2761 MapConstPtr_Type map = this->domainVec_.at(0)->getMapRepeated();
2763 vec_dbl_Type solution_u;
2764 vec_dbl_ptr_Type rhsVec;
2767 if (FEType ==
"P2") {
2772 if (FEType ==
"P2") {
2781 tuple_disk_vec_ptr_Type problemDisk =
2782 Teuchos::rcp(
new tuple_disk_vec_Type(0));
2783 tuple_ssii_Type temp(
"Solution", FEType, dofs, numNodes);
2784 problemDisk->push_back(temp);
2787 if (assemblyFEElements_.size() == 0) {
2788 initAssembleFEElements(
"NonLinearLaplace", problemDisk, elements, params, pointsRep, domainVec_.at(0)->getElementMap());
2789 }
else if (assemblyFEElements_.size() != elements->numberElements()) {
2790 TEUCHOS_TEST_FOR_EXCEPTION(
2791 true, std::logic_error,
2792 "Number Elements not the same as number assembleFE elements.");
2795 MultiVectorPtr_Type resVec_u;
2796 BlockMultiVectorPtr_Type resVecRep;
2798 if (assembleMode !=
"Rhs") {
2802 auto A_block_zero_zero = Teuchos::rcp(
2803 new Matrix_Type(this->domainVec_.at(0)->getMapUnique(), this->domainVec_.at(0)->getApproxEntriesPerRow()));
2805 A->addBlock(A_block_zero_zero, 0, 0);
2808 resVec_u = Teuchos::rcp(
new MultiVector_Type(map, 1));
2809 resVecRep = Teuchos::rcp(
new BlockMultiVector_Type(1));
2810 resVecRep->addBlock(resVec_u, 0);
2813 for (UN T = 0; T < assemblyFEElements_.size(); T++) {
2814 vec_dbl_Type solution(0);
2817 solution_u = getSolution(elements->getElement(T).getVectorNodeList(),
2819 solution.insert(solution.end(), solution_u.begin(), solution_u.end());
2820 assemblyFEElements_[T]->updateSolution(solution);
2822 if (assembleMode ==
"Jacobian") {
2823 SmallMatrixPtr_Type elementMatrix;
2824 assemblyFEElements_[T]->assembleJacobian();
2825 elementMatrix = assemblyFEElements_[T]->getJacobian();
2828 assemblyFEElements_[T]
2829 ->advanceNewtonStep();
2830 addFeBlock(A, elementMatrix, elements->getElement(T), map, 0, 0,
2834 if (assembleMode ==
"Rhs") {
2835 assemblyFEElements_[T]->assembleRHS();
2836 rhsVec = assemblyFEElements_[T]->getRHS();
2841 addFeBlockMv(resVecRep, rhsVec, elements->getElement(T), dofs);
2844 if (callFillComplete && assembleMode !=
"Rhs") {
2847 A->getBlock(0, 0)->fillComplete(domainVec_.at(0)->getMapUnique(),
2848 domainVec_.at(0)->getMapUnique());
2850 if (assembleMode ==
"Rhs") {
2852 MultiVectorPtr_Type resVecUnique = Teuchos::rcp(
2853 new MultiVector_Type(domainVec_.at(0)->getMapUnique(), 1));
2854 resVecUnique->putScalar(0.);
2855 resVecUnique->exportFromVector(resVec_u,
true,
"Add");
2856 resVec->addBlock(resVecUnique, 0);
2861template <
class SC,
class LO,
class GO,
class NO>
2862void FE<SC,LO,GO,NO>::assemblyElasticityJacobianAndStressAceFEM(
int dim,
2865 MultiVectorPtr_Type &f,
2866 MultiVectorPtr_Type u,
2867 ParameterListPtr_Type pList,
2869 bool callFillComplete){
2870 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::runtime_error,
"Not implemented for P0");
2871 UN FEloc = checkFE(dim,FEType);
2874 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
2875 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
2877 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
2878 vec3D_dbl_ptr_Type dPhi;
2879 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
2890 Teuchos::BLAS<int,SC> teuchosBLAS;
2892 int nmbQuadPoints = dPhi->size();
2893 int nmbScalarDPhi = dPhi->at(0).size();
2894 int nmbAllDPhi = nmbScalarDPhi * dim;
2895 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
2896 int sizeLocStiff = dim*dim;
2897 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud,
SmallMatrix<SC>(dim) );
2899 this->buildFullDPhi( dPhi, dPhiMat );
2901 std::string material_model = pList->sublist(
"Parameter").get(
"Material model",
"Neo-Hooke");
2903 double poissonRatio = pList->sublist(
"Parameter").get(
"Poisson Ratio",0.4);
2904 double mue = pList->sublist(
"Parameter").get(
"Mu",2.0e+6);
2905 double mue1 = pList->sublist(
"Parameter").get(
"Mu1",2.0e+6);
2906 double mue2 = pList->sublist(
"Parameter").get(
"Mu2",2.0e+6);
2908 double E = pList->sublist(
"Parameter").get(
"E",3.0e+6);
2909 double E1 = pList->sublist(
"Parameter").get(
"E1",3.0e+6);
2910 double E2 = pList->sublist(
"Parameter").get(
"E2",3.0e+6);
2912 if (material_model==
"Saint Venant-Kirchhoff") {
2913 E = mue*2.*(1. + poissonRatio);
2914 E1 = mue1*2.*(1. + poissonRatio);
2915 E2 = mue2*2.*(1. + poissonRatio);
2919 double lambda = (poissonRatio*E)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2920 double lambda1 = (poissonRatio*E1)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2921 double lambda2 = (poissonRatio*E2)/((1 + poissonRatio)*(1 - 2*poissonRatio));
2925 if(!material_model.compare(
"Saint Venant-Kirchhoff"))
2926 v =
new double[154];
2928 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only Saint Venant-Kirchhoff in 2D.");
2930 double** Pmat =
new double*[2];
2931 for (
int i=0; i<2; i++)
2932 Pmat[i] =
new double[2];
2934 double** F =
new double*[2];
2935 for (
int i=0; i<2; i++)
2936 F[i] =
new double[2];
2938 double**** Amat =
new double***[2];
2939 for (
int i=0; i<2; i++){
2940 Amat[i] =
new double**[2];
2941 for (
int j=0; j<2; j++) {
2942 Amat[i][j] =
new double*[2];
2943 for (
int k=0; k<2; k++)
2944 Amat[i][j][k] =
new double[2];
2948 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
2950 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
2952 Teuchos::Array<int> indices(2);
2953 for (
int T=0; T<elements->numberElements(); T++) {
2955 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType);
2956 detB = B.computeInverse(Binv);
2957 absDetB = std::fabs(detB);
2959 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
2961 for (
int i=0; i<all_dPhiMat_Binv.size(); i++) {
2962 SmallMatrix<SC> res = dPhiMat[i] * Binv;
2963 all_dPhiMat_Binv[i] = res;
2966 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
2967 std::vector<SC> locStresses( nmbAllDPhi, 0. );
2968 int elementFlag = 0;
2969 for (
int p=0; p<nmbQuadPoints; p++){
2971 SmallMatrix<SC> Fmat( dim, 0. );
2972 SmallMatrix<SC> tmpForScaling( dim, 0. );
2973 Fmat[0][0] = 1.; Fmat[1][1] = 1.;
2975 for (
int i=0; i<nmbScalarDPhi; i++) {
2976 indices.at(0) = dim * elements->getElement(T).getNode(i);
2977 indices.at(1) = dim * elements->getElement(T).getNode(i) + 1;
2979 for (
int j=0; j<dim; j++) {
2980 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ];
2981 SC v = uArray[indices.at(j)];
2982 tmpForScaling.scale( v );
2983 Fmat += tmpForScaling;
2987 for (
int i=0; i<Fmat.size(); i++) {
2988 for (
int j=0; j<Fmat.size(); j++) {
2989 F[i][j] = Fmat[i][j];
2993 elementFlag = elements->getElement(T).getFlag();
2994 if (elementFlag == 1){
2999 else if (elementFlag == 2){
3005 if ( !material_model.compare(
"Saint Venant-Kirchhoff") )
3006 stvk2d(v, &lambda, &mue, F, Pmat, Amat);
3008 SmallMatrix<SC> Aloc(dim*dim);
3009 for (
int i=0; i<2; i++) {
3010 for (
int j=0; j<2; j++) {
3011 for (
int k=0; k<2; k++) {
3012 for (
int l=0; l<2; l++) {
3013 Aloc[ 2 * i + j ][ 2 * k + l ] = Amat[i][j][k][l];
3019 double* aceFEMFunc =
new double[ sizeLocStiff * sizeLocStiff ];
3020 double* allDPhiBlas =
new double[ nmbAllDPhi * sizeLocStiff ];
3023 double* resTmp =
new double[ nmbAllDPhi * sizeLocStiff ];
3025 fillMatrixArray(Aloc, aceFEMFunc,
"cols");
3027 int offset = p * nmbAllDPhi;
3028 int offsetInArray = 0;
3029 for (
int i=0; i<nmbAllDPhi; i++) {
3030 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas,
"rows",offsetInArray );
3031 offsetInArray += sizeLocStiff;
3034 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
3037 double* locStiffMatBlas =
new double[ nmbAllDPhi * nmbAllDPhi ];
3039 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
3041 for (
int i=0; i<nmbAllDPhi; i++) {
3042 for (
int j=0; j<nmbAllDPhi; j++)
3043 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
3047 delete [] locStiffMatBlas;
3051 double* fArray =
new double[ sizeLocStiff ];
3052 for (
int i=0; i<dim; i++) {
3053 for (
int j=0; j<dim; j++) {
3054 fArray[i * dim + j] = Pmat[i][j];
3058 double* res =
new double[ nmbAllDPhi ];
3059 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
3060 for (
int i=0; i<locStresses.size(); i++) {
3061 locStresses[i] += weights->at(p) * res[i];
3065 delete [] aceFEMFunc;
3066 delete [] allDPhiBlas;
3070 for (
int i=0; i<nmbScalarDPhi; i++) {
3071 for (
int d1=0; d1<dim; d1++) {
3073 LO rowLO = dim * elements->getElement(T).getNode(i) + d1;
3074 SC v = absDetB * locStresses[ dim * i + d1 ];
3075 fValues[rowLO] += v;
3077 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
3078 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
3080 for (UN j=0; j < nmbScalarDPhi; j++){
3081 for (UN d2=0; d2<dim; d2++) {
3082 indices[counter] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
3083 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
3087 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
3088 A->insertGlobalValues( row, indices(), value() );
3094 for (
int i=0; i<2; i++)
3097 for (
int i=0; i<2; i++)
3101 for (
int i=0; i<2; i++){
3102 for (
int j=0; j<2; j++) {
3103 for (
int k=0; k<2; k++)
3104 delete [] Amat[i][j][k];
3105 delete [] Amat[i][j];
3113 else if (dim == 3) {
3115 if (!material_model.compare(
"Neo-Hooke"))
3116 v =
new double[466];
3117 else if(!material_model.compare(
"Mooney-Rivlin"))
3118 v =
new double[476];
3119 else if(!material_model.compare(
"Saint Venant-Kirchhoff"))
3120 v =
new double[279];
3122 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only Neo-Hooke, Mooney-Rivlin and Saint Venant-Kirchhoff.");
3125 double** Pmat =
new double*[3];
3126 for (
int i=0; i<3; i++)
3127 Pmat[i] =
new double[3];
3129 double** F =
new double*[3];
3130 for (
int i=0; i<3; i++)
3131 F[i] =
new double[3];
3133 double**** Amat =
new double***[3];
3134 for (
int i=0; i<3; i++){
3135 Amat[i] =
new double**[3];
3136 for (
int j=0; j<3; j++) {
3137 Amat[i][j] =
new double*[3];
3138 for (
int k=0; k<3; k++)
3139 Amat[i][j][k] =
new double[3];
3143 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3145 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
3147 Teuchos::Array<int> indices(3);
3148 for (
int T=0; T<elements->numberElements(); T++) {
3150 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType);
3151 detB = B.computeInverse(Binv);
3152 absDetB = std::fabs(detB);
3154 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3156 for (
int i=0; i<all_dPhiMat_Binv.size(); i++) {
3157 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3158 all_dPhiMat_Binv[i] = res;
3161 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
3162 std::vector<SC> locStresses( nmbAllDPhi, 0. );
3163 int elementFlag = 0;
3164 for (
int p=0; p<nmbQuadPoints; p++){
3166 SmallMatrix<SC> Fmat( dim, 0. );
3167 SmallMatrix<SC> tmpForScaling( dim, 0. );
3168 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3170 for (
int i=0; i<nmbScalarDPhi; i++) {
3171 indices.at(0) = dim * elements->getElement(T).getNode(i);
3172 indices.at(1) = dim * elements->getElement(T).getNode(i) + 1;
3173 indices.at(2) = dim * elements->getElement(T).getNode(i) + 2;
3175 for (
int j=0; j<dim; j++) {
3176 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ];
3177 SC v = uArray[indices.at(j)];
3178 tmpForScaling.scale( v );
3179 Fmat += tmpForScaling;
3183 for (
int i=0; i<Fmat.size(); i++) {
3184 for (
int j=0; j<Fmat.size(); j++) {
3185 F[i][j] = Fmat[i][j];
3189 elementFlag = elements->getElement(T).getFlag();
3190 if (elementFlag == 1){
3195 else if (elementFlag == 2){
3201 if ( !material_model.compare(
"Neo-Hooke") )
3202 nh3d(v, &E, &poissonRatio, F, Pmat, Amat);
3203 else if ( !material_model.compare(
"Mooney-Rivlin") )
3204 mr3d(v, &E, &poissonRatio, &C, F, Pmat, Amat);
3205 else if ( !material_model.compare(
"Saint Venant-Kirchhoff") )
3206 stvk3d(v, &lambda, &mue, F, Pmat, Amat);
3208 SmallMatrix<SC> Aloc(dim*dim);
3209 for (
int i=0; i<3; i++) {
3210 for (
int j=0; j<3; j++) {
3211 for (
int k=0; k<3; k++) {
3212 for (
int l=0; l<3; l++) {
3213 Aloc[ 3 * i + j ][ 3 * k + l ] = Amat[i][j][k][l];
3219 double* aceFEMFunc =
new double[ sizeLocStiff * sizeLocStiff ];
3220 double* allDPhiBlas =
new double[ nmbAllDPhi * sizeLocStiff ];
3223 double* resTmp =
new double[ nmbAllDPhi * sizeLocStiff ];
3225 fillMatrixArray(Aloc, aceFEMFunc,
"cols");
3227 int offset = p * nmbAllDPhi;
3228 int offsetInArray = 0;
3229 for (
int i=0; i<nmbAllDPhi; i++) {
3230 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas,
"rows",offsetInArray );
3231 offsetInArray += sizeLocStiff;
3234 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
3237 double* locStiffMatBlas =
new double[ nmbAllDPhi * nmbAllDPhi ];
3239 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
3241 for (
int i=0; i<nmbAllDPhi; i++) {
3242 for (
int j=0; j<nmbAllDPhi; j++)
3243 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
3247 delete [] locStiffMatBlas;
3251 double* fArray =
new double[ sizeLocStiff ];
3252 for (
int i=0; i<dim; i++) {
3253 for (
int j=0; j<dim; j++) {
3254 fArray[i * dim + j] = Pmat[i][j];
3258 double* res =
new double[ nmbAllDPhi ];
3259 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
3260 for (
int i=0; i<locStresses.size(); i++) {
3261 locStresses[i] += weights->at(p) * res[i];
3265 delete [] aceFEMFunc;
3266 delete [] allDPhiBlas;
3270 for (
int i=0; i<nmbScalarDPhi; i++) {
3271 for (
int d1=0; d1<dim; d1++) {
3273 LO rowLO = dim * elements->getElement(T).getNode(i) + d1;
3274 SC v = absDetB * locStresses[ dim * i + d1 ];
3275 fValues[rowLO] += v;
3277 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
3278 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
3280 for (UN j=0; j < nmbScalarDPhi; j++){
3281 for (UN d2=0; d2<dim; d2++) {
3282 indices[counter] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
3283 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
3288 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
3289 A->insertGlobalValues( row, indices(), value() );
3295 for (
int i=0; i<3; i++)
3298 for (
int i=0; i<3; i++)
3302 for (
int i=0; i<3; i++){
3303 for (
int j=0; j<3; j++) {
3304 for (
int k=0; k<3; k++)
3305 delete [] Amat[i][j][k];
3306 delete [] Amat[i][j];
3313 if (callFillComplete)
3319template <
class SC,
class LO,
class GO,
class NO>
3320void FE<SC,LO,GO,NO>::assemblyElasticityJacobianAceFEM(
int dim,
3323 MultiVectorPtr_Type u,
3324 std::string material_model,
3328 bool callFillComplete){
3329 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
3330 UN FEloc = checkFE(dim,FEType);
3332 vec2D_int_ptr_Type elements = domainVec_.at(FEloc)->getElements();
3334 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3336 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3337 vec3D_dbl_ptr_Type dPhi;
3338 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
3340 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
3342 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3346 SmallMatrix<SC> B(dim);
3347 SmallMatrix<SC> Binv(dim);
3349 Teuchos::BLAS<int, SC> teuchosBLAS;
3351 int nmbQuadPoints = dPhi->size();
3352 int nmbScalarDPhi = dPhi->at(0).size();
3353 int nmbAllDPhi = nmbScalarDPhi * dim;
3354 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
3355 int sizeLocStiff = dim*dim;
3356 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<SC>(dim) );
3358 this->buildFullDPhi( dPhi, dPhiMat );
3361 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only for 3D.");
3363 else if (dim == 3) {
3366 if (!material_model.compare(
"Neo-Hooke"))
3367 v =
new double[466];
3368 else if(!material_model.compare(
"Mooney-Rivlin"))
3369 v =
new double[476];
3371 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only Neo-Hooke and Mooney-Rivlin.");
3375 double** Pmat =
new double*[3];
3376 for (
int i=0; i<3; i++)
3377 Pmat[i] =
new double[3];
3379 double** F =
new double*[3];
3380 for (
int i=0; i<3; i++)
3381 F[i] =
new double[3];
3383 double**** Amat =
new double***[3];
3384 for (
int i=0; i<3; i++){
3385 Amat[i] =
new double**[3];
3386 for (
int j=0; j<3; j++) {
3387 Amat[i][j] =
new double*[3];
3388 for (
int k=0; k<3; k++)
3389 Amat[i][j][k] =
new double[3];
3393 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3395 Teuchos::Array<int> indices(3);
3396 for (
int T=0; T<elements->size(); T++) {
3398 Helper::buildTransformation(elements->at(T), pointsRep, B,FEType);
3399 detB = B.computeInverse(Binv);
3400 absDetB = std::fabs(detB);
3402 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3404 for (
int i=0; i<all_dPhiMat_Binv.size(); i++) {
3405 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3406 all_dPhiMat_Binv[i] = res;
3409 SmallMatrix<SC> locStiffMat( nmbAllDPhi, 0. );
3411 for (
int p=0; p<nmbQuadPoints; p++){
3413 SmallMatrix<SC> Fmat( dim, 0. );
3414 SmallMatrix<SC> tmpForScaling( dim, 0. );
3415 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3417 for (
int i=0; i<nmbScalarDPhi; i++) {
3418 indices.at(0) = dim * elements->at(T).at(i);
3419 indices.at(1) = dim * elements->at(T).at(i) + 1;
3420 indices.at(2) = dim * elements->at(T).at(i) + 2;
3422 for (
int j=0; j<dim; j++) {
3423 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ];
3424 SC v = uArray[indices.at(j)];
3425 tmpForScaling.scale( v );
3426 Fmat += tmpForScaling;
3430 for (
int i=0; i<Fmat.size(); i++) {
3431 for (
int j=0; j<Fmat.size(); j++) {
3432 F[i][j] = Fmat[i][j];
3435 if ( !material_model.compare(
"Neo-Hooke") )
3436 nh3d(v, &E, &nu, F, Pmat, Amat);
3437 else if ( !material_model.compare(
"Mooney-Rivlin") )
3438 mr3d(v, &E, &nu, &C, F, Pmat, Amat);
3440 SmallMatrix<SC> Aloc(dim*dim);
3441 for (
int i=0; i<3; i++) {
3442 for (
int j=0; j<3; j++) {
3443 for (
int k=0; k<3; k++) {
3444 for (
int l=0; l<3; l++) {
3445 Aloc[ 3 * i + j ][ 3 * k + l ] = Amat[i][j][k][l];
3451 double* aceFEMFunc =
new double[ sizeLocStiff * sizeLocStiff ];
3452 double* allDPhiBlas =
new double[ nmbAllDPhi * sizeLocStiff ];
3453 double* resTmp =
new double[ nmbAllDPhi * sizeLocStiff ];
3455 fillMatrixArray(Aloc, aceFEMFunc,
"cols");
3457 int offset = p * nmbAllDPhi;
3458 int offsetInArray = 0;
3459 for (
int i=0; i<nmbAllDPhi; i++) {
3460 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas,
"rows",offsetInArray );
3461 offsetInArray += sizeLocStiff;
3464 teuchosBLAS.GEMM (Teuchos::NO_TRANS, Teuchos::NO_TRANS, sizeLocStiff, nmbAllDPhi, sizeLocStiff, 1., aceFEMFunc, sizeLocStiff, allDPhiBlas, sizeLocStiff, 0., resTmp, sizeLocStiff);
3466 double* locStiffMatBlas =
new double[ nmbAllDPhi * nmbAllDPhi ];
3468 teuchosBLAS.GEMM (Teuchos::TRANS, Teuchos::NO_TRANS, nmbAllDPhi, nmbAllDPhi, sizeLocStiff, 1., allDPhiBlas, sizeLocStiff, resTmp, sizeLocStiff, 0., locStiffMatBlas, nmbAllDPhi);
3470 for (
int i=0; i<nmbAllDPhi; i++) {
3471 for (
int j=0; j<nmbAllDPhi; j++)
3472 locStiffMat[i][j] += weights->at(p) * locStiffMatBlas[ j * nmbAllDPhi + i ];
3475 delete [] aceFEMFunc;
3476 delete [] allDPhiBlas;
3478 delete [] locStiffMatBlas;
3481 for (
int i=0; i<nmbScalarDPhi; i++) {
3482 for (
int d1=0; d1<dim; d1++) {
3483 Teuchos::Array<SC> value( nmbAllDPhi, 0. );
3484 Teuchos::Array<GO> indices( nmbAllDPhi, 0 );
3486 for (UN j=0; j < nmbScalarDPhi; j++){
3487 for (UN d2=0; d2<dim; d2++) {
3488 indices[counter] = GO ( dim * map->getGlobalElement( elements->at(T).at(j) ) + d2 );
3489 value[counter] = absDetB * locStiffMat[dim*i+d1][dim*j+d2];
3493 GO row = GO ( dim * map->getGlobalElement( elements->at(T).at(i) ) + d1 );
3494 A->insertGlobalValues( row, indices(), value() );
3500 for (
int i=0; i<3; i++)
3503 for (
int i=0; i<3; i++)
3507 for (
int i=0; i<3; i++){
3508 for (
int j=0; j<3; j++) {
3509 for (
int k=0; k<3; k++)
3510 delete [] Amat[i][j][k];
3511 delete [] Amat[i][j];
3518 if (callFillComplete)
3523template <
class SC,
class LO,
class GO,
class NO>
3524void FE<SC,LO,GO,NO>::assemblyElasticityStressesAceFEM(
int dim,
3526 MultiVectorPtr_Type &f,
3527 MultiVectorPtr_Type u,
3528 std::string material_model,
3532 bool callFillComplete){
3533 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
3534 UN FEloc = checkFE(dim,FEType);
3536 vec2D_int_ptr_Type elements = domainVec_.at(FEloc)->getElements();
3538 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3540 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3542 vec3D_dbl_ptr_Type dPhi;
3543 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
3545 UN deg = 2*Helper::determineDegree(dim,FEType,Helper::Deriv1);
3547 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
3551 SmallMatrix<SC> B(dim);
3552 SmallMatrix<SC> Binv(dim);
3554 Teuchos::BLAS<int, SC> teuchosBLAS;
3556 int nmbQuadPoints = dPhi->size();
3557 int nmbScalarDPhi = dPhi->at(0).size();
3558 int nmbAllDPhi = nmbScalarDPhi * dim;
3559 int nmbAllDPhiAllQaud = nmbQuadPoints * nmbAllDPhi;
3560 int sizeLocStiff = dim*dim;
3561 Teuchos::Array<SmallMatrix<SC> > dPhiMat( nmbAllDPhiAllQaud, SmallMatrix<SC>(dim) );
3563 this->buildFullDPhi( dPhi, dPhiMat );
3566 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only for 3D.");
3568 else if (dim == 3) {
3571 if (!material_model.compare(
"Neo-Hooke"))
3572 v =
new double[466];
3573 else if(!material_model.compare(
"Mooney-Rivlin"))
3574 v =
new double[476];
3576 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Only Neo-Hooke and Mooney-Rivlin.");
3580 double** Pmat =
new double*[3];
3581 for (
int i=0; i<3; i++)
3582 Pmat[i] =
new double[3];
3584 double** F =
new double*[3];
3585 for (
int i=0; i<3; i++)
3586 F[i] =
new double[3];
3588 double**** Amat =
new double***[3];
3589 for (
int i=0; i<3; i++){
3590 Amat[i] =
new double**[3];
3591 for (
int j=0; j<3; j++) {
3592 Amat[i][j] =
new double*[3];
3593 for (
int k=0; k<3; k++)
3594 Amat[i][j][k] =
new double[3];
3598 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3600 Teuchos::ArrayRCP<SC> fValues = f->getDataNonConst(0);
3602 Teuchos::Array<int> indices(3);
3603 for (
int T=0; T<elements->size(); T++) {
3605 Helper::buildTransformation(elements->at(T), pointsRep, B,FEType);
3606 detB = B.computeInverse(Binv);
3607 absDetB = std::fabs(detB);
3609 Teuchos::Array<SmallMatrix<SC> > all_dPhiMat_Binv( dPhiMat.size(), SmallMatrix<SC>() );
3611 for (
int i=0; i<all_dPhiMat_Binv.size(); i++) {
3612 SmallMatrix<SC> res = dPhiMat[i] * Binv;
3613 all_dPhiMat_Binv[i] = res;
3615 std::vector<double> locStresses( nmbAllDPhi, 0. );
3617 for (
int p=0; p<nmbQuadPoints; p++){
3619 SmallMatrix<SC> Fmat( dim, 0. );
3620 SmallMatrix<SC> tmpForScaling( dim, 0. );
3621 Fmat[0][0] = 1.; Fmat[1][1] = 1.; Fmat[2][2] = 1.;
3623 for (
int i=0; i<nmbScalarDPhi; i++) {
3624 indices.at(0) = dim * elements->at(T).at(i);
3625 indices.at(1) = dim * elements->at(T).at(i) + 1;
3626 indices.at(2) = dim * elements->at(T).at(i) + 2;
3628 for (
int j=0; j<dim; j++) {
3629 tmpForScaling = all_dPhiMat_Binv[ p * nmbAllDPhi + dim * i + j ];
3630 SC v = uArray[indices.at(j)];
3631 tmpForScaling.scale( v );
3632 Fmat += tmpForScaling;
3636 for (
int i=0; i<Fmat.size(); i++) {
3637 for (
int j=0; j<Fmat.size(); j++) {
3638 F[i][j] = Fmat[i][j];
3641 if ( !material_model.compare(
"Neo-Hooke") )
3642 nh3d(v, &E, &nu, F, Pmat, Amat);
3643 else if ( !material_model.compare(
"Mooney-Rivlin") )
3644 mr3d(v, &E, &nu, &C, F, Pmat, Amat);
3646 double* aceFEMFunc =
new double[ sizeLocStiff * sizeLocStiff ];
3647 double* allDPhiBlas =
new double[ nmbAllDPhi * sizeLocStiff ];
3649 int offset = p * nmbAllDPhi;
3650 int offsetInArray = 0;
3651 for (
int i=0; i<nmbAllDPhi; i++) {
3652 fillMatrixArray( all_dPhiMat_Binv[ offset + i ], allDPhiBlas,
"rows",offsetInArray );
3653 offsetInArray += sizeLocStiff;
3657 double* fArray =
new double[ sizeLocStiff ];
3658 for (
int i=0; i<dim; i++) {
3659 for (
int j=0; j<dim; j++) {
3660 fArray[i * dim + j] = Pmat[i][j];
3664 double* res =
new double[ nmbAllDPhi ];
3665 teuchosBLAS.GEMV(Teuchos::TRANS, sizeLocStiff, nmbAllDPhi, 1., allDPhiBlas, sizeLocStiff, fArray, 1, 0., res, 1);
3666 for (
int i=0; i<locStresses.size(); i++) {
3667 locStresses[i] += weights->at(p) * res[i];
3670 delete [] aceFEMFunc;
3671 delete [] allDPhiBlas;
3677 for (
int i=0; i<nmbScalarDPhi; i++) {
3678 for (
int d1=0; d1<dim; d1++) {
3679 LO row = dim * elements->at(T).at(i) + d1;
3680 SC v = absDetB * locStresses[ dim * i + d1 ];
3688 for (
int i=0; i<3; i++)
3691 for (
int i=0; i<3; i++)
3695 for (
int i=0; i<3; i++){
3696 for (
int j=0; j<3; j++) {
3697 for (
int k=0; k<3; k++)
3698 delete [] Amat[i][j][k];
3699 delete [] Amat[i][j];
3709template <
class SC,
class LO,
class GO,
class NO>
3713 MultiVectorPtr_Type u,
3714 bool callFillComplete){
3716 TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error,
"Implement for numberMV > 1 ." );
3717 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
3719 UN FEloc = checkFE(dim,FEType);
3721 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
3723 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3725 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3727 vec3D_dbl_ptr_Type dPhi;
3728 vec2D_dbl_ptr_Type phi;
3729 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
3744 vec_dbl_Type v_i(dim);
3745 vec_dbl_Type v_j(dim);
3747 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
3748 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3750 for (UN T=0; T<elements->numberElements(); T++) {
3753 detB = B.computeInverse(Binv);
3754 absDetB = std::fabs(detB);
3756 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3757 applyBTinv( dPhi, dPhiTrans, Binv );
3759 for (
int w=0; w<phi->size(); w++){
3760 for (
int d=0; d<dim; d++) {
3762 for (
int i=0; i < phi->at(0).size(); i++) {
3763 LO index = dim * elements->getElement(T).getNode(i) + d;
3764 uLoc[d][w] += uArray[index] * phi->at(w).at(i);
3769 for (UN i=0; i < phi->at(0).size(); i++) {
3770 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
3771 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
3772 for (UN j=0; j < value.size(); j++) {
3773 for (UN w=0; w<dPhiTrans.size(); w++) {
3774 for (UN d=0; d<dim; d++){
3775 value[j] += weights->at(w) * uLoc[d][w] * (*phi)[w][i] * dPhiTrans[w][j][d];
3779 value[j] *= absDetB;
3780 if (setZeros_ && std::fabs(value[j]) < myeps_) {
3784 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) );
3785 GO glob_j = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) );
3787 for (UN d=0; d<dim; d++) {
3788 for (UN j=0; j < indices.size(); j++)
3789 indices[j] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d );
3791 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d );
3792 A->insertGlobalValues( row, indices(), value() );
3798 if (callFillComplete)
3803template <
class SC,
class LO,
class GO,
class NO>
3807 MultiVectorPtr_Type u,
3808 bool callFillComplete){
3810 TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error,
"Implement for numberMV > 1 ." );
3811 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
3812 UN FEloc = checkFE(dim,FEType);
3814 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
3816 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
3818 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
3820 vec3D_dbl_ptr_Type dPhi;
3821 vec2D_dbl_ptr_Type phi;
3822 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
3836 vec_dbl_Type v_i(dim);
3837 vec_dbl_Type v_j(dim);
3839 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3841 for (UN T=0; T<elements->numberElements(); T++) {
3844 detB = B.computeInverse(Binv);
3845 absDetB = std::fabs(detB);
3847 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3848 applyBTinv( dPhi, dPhiTrans, Binv );
3850 std::vector<SmallMatrix<SC> > duLoc( weights->size(),
SmallMatrix<SC>(dim) );
3852 for (
int w=0; w<dPhiTrans.size(); w++){
3853 for (
int d1=0; d1<dim; d1++) {
3854 for (
int i=0; i < dPhiTrans[0].size(); i++) {
3855 LO index = dim * elements->getElement(T).getNode(i) + d1;
3856 for (
int d2=0; d2<dim; d2++)
3857 duLoc[w][d2][d1] += uArray[index] * dPhiTrans[w][i][d2];
3862 for (UN i=0; i < phi->at(0).size(); i++) {
3863 for (UN d1=0; d1<dim; d1++) {
3864 Teuchos::Array<SC> value( dim*phi->at(0).size(), 0. );
3865 Teuchos::Array<GO> indices( dim*phi->at(0).size(), 0 );
3866 for (UN j=0; j < phi->at(0).size(); j++) {
3867 for (UN d2=0; d2<dim; d2++){
3868 for (UN w=0; w<phi->size(); w++) {
3869 value[ dim * j + d2 ] += weights->at(w) * duLoc[w][d2][d1] * (*phi)[w][i] * (*phi)[w][j];
3871 value[ dim * j + d2 ] *= absDetB;
3873 if (setZeros_ && std::fabs(value[ dim * j + d2 ]) < myeps_) {
3874 value[ dim * j + d2 ] = 0.;
3878 for (UN j=0; j < phi->at(0).size(); j++){
3879 for (UN d2=0; d2<dim; d2++){
3880 indices[ dim * j + d2 ] = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(j) ) + d2 );
3884 GO row = GO ( dim * map->getGlobalElement( elements->getElement(T).getNode(i) ) + d1 );
3885 A->insertGlobalValues( row, indices(), value() );
3889 if (callFillComplete)
3894template <
class SC,
class LO,
class GO,
class NO>
3897 std::string FETypeV,
3899 MultiVectorPtr_Type u,
3900 bool callFillComplete){
3902 TEUCHOS_TEST_FOR_EXCEPTION( u->getNumVectors()>1, std::logic_error,
"Implement for numberMV > 1 ." );
3903 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
3905 UN FEloc = checkFE(dim,FEType);
3907 ElementsPtr_Type elements = domainVec_.at(1)->getElementsC();
3908 ElementsPtr_Type elementsVel = domainVec_.at(0)->getElementsC();
3910 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(1)->getPointsRepeated();
3912 MapConstPtr_Type map = domainVec_.at(1)->getMapRepeated();
3914 vec3D_dbl_ptr_Type dPhi;
3915 vec2D_dbl_ptr_Type phi,phiV;
3916 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
3931 vec_dbl_Type v_i(dim);
3932 vec_dbl_Type v_j(dim);
3934 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
3935 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
3937 for (UN T=0; T<elements->numberElements(); T++) {
3940 detB = B.computeInverse(Binv);
3941 absDetB = std::fabs(detB);
3943 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
3944 applyBTinv( dPhi, dPhiTrans, Binv );
3946 for (
int w=0; w<phiV->size(); w++){
3947 for (
int d=0; d<dim; d++) {
3949 for (
int i=0; i < phiV->at(0).size(); i++) {
3950 LO index = dim * elementsVel->getElement(T).getNode(i) + d;
3951 uLoc[d][w] += uArray[index] * phiV->at(w).at(i);
3956 for (UN i=0; i < phi->at(0).size(); i++) {
3957 Teuchos::Array<SC> value( dPhiTrans[0].size(), 0. );
3958 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
3959 for (UN j=0; j < value.size(); j++) {
3960 for (UN w=0; w<dPhiTrans.size(); w++) {
3961 for (UN d=0; d<dim; d++){
3962 value[j] += weights->at(w) * uLoc[d][w]* dPhiTrans[w][j][d] * (*phi)[w][i] ;
3965 value[j] *= absDetB;
3966 indices[j] = GO ( map->getGlobalElement( elements->getElement(T).getNode(j) ) );
3969 GO row = GO ( map->getGlobalElement( elements->getElement(T).getNode(i) ) );
3970 A->insertGlobalValues( row, indices(), value() );
3976 if (callFillComplete)
3981template <
class SC,
class LO,
class GO,
class NO>
3983 std::string FEType1,
3984 std::string FEType2,
3986 MatrixPtr_Type &Bmat,
3987 MatrixPtr_Type &BTmat,
3988 MapConstPtr_Type map1,
3989 MapConstPtr_Type map2,
3990 bool callFillComplete) {
3993 UN FEloc1 = checkFE(dim,FEType1);
3994 UN FEloc2 = checkFE(dim,FEType2);
3996 ElementsPtr_Type elements1 = domainVec_.at(FEloc1)->getElementsC();
3997 ElementsPtr_Type elements2 = domainVec_.at(FEloc2)->getElementsC();
3999 vec2D_dbl_ptr_Type pointsRep1 = domainVec_.at(FEloc1)->getPointsRepeated();
4001 MapConstPtr_Type mapping1 = domainVec_.at(FEloc1)->getMapRepeated();
4002 MapConstPtr_Type mapping2;
4004 if (FEType2 ==
"P0")
4005 mapping2 = domainVec_.at(FEloc2)->getElementMap();
4007 mapping2 = domainVec_.at(FEloc2)->getMapRepeated();
4009 vec3D_dbl_ptr_Type dPhi;
4010 vec2D_dbl_ptr_Type phi;
4011 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
4020 if (FEType2==
"P1-disc" && FEType1==
"Q2" )
4030 vec_dbl_Type v_i(dim);
4031 vec_dbl_Type v_j(dim);
4033 for (UN T=0; T<elements1->numberElements(); T++) {
4036 detB = B.computeInverse(Binv);
4037 absDetB = std::fabs(detB);
4039 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4040 applyBTinv( dPhi, dPhiTrans, Binv );
4042 for (UN i=0; i < phi->at(0).size(); i++) {
4043 Teuchos::Array<Teuchos::Array<SC> >valueVec( dim, Teuchos::Array<SC>( dPhiTrans[0].size(), 0. ) );
4044 Teuchos::Array<GO> indices( dPhiTrans[0].size(), 0 );
4046 for (UN j=0; j < valueVec[0].size(); j++) {
4047 for (UN w=0; w<dPhiTrans.size(); w++) {
4048 for (UN d=0; d<dim; d++)
4049 valueVec[d][j] += weights->at(w) * phi->at(w)[i] * dPhiTrans[w][j][d];
4051 for (UN d=0; d<dim; d++){
4052 valueVec[d][j] *= absDetB;
4053 if (setZeros_ && std::fabs(valueVec[d][j]) < myeps_) {
4054 valueVec[d][j] = 0.;
4058 for (UN d=0; d<dim; d++) {
4059 for (UN j=0; j < indices.size(); j++)
4060 indices[j] = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(j) ) + d );
4064 row = GO ( mapping2->getGlobalElement( T ) );
4066 row = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(i) ) );
4067 Bmat->insertGlobalValues( row, indices(), valueVec[d]() );
4072 for (UN i=0; i < dPhiTrans[0].size(); i++) {
4074 Teuchos::Array<Teuchos::Array<SC> >valueVec( dim, Teuchos::Array<SC>( phi->at(0).size(), 0. ) );
4075 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
4076 for (UN j=0; j < valueVec[0].size(); j++) {
4077 for (UN w=0; w<dPhiTrans.size(); w++) {
4078 for (UN d=0; d<dim; d++)
4079 valueVec[d][j] += weights->at(w) * phi->at(w)[j] * dPhiTrans[w][i][d];
4081 for (UN d=0; d<dim; d++){
4082 valueVec[d][j] *= absDetB;
4083 if (setZeros_ && std::fabs(valueVec[d][j]) < myeps_) {
4084 valueVec[d][j] = 0.;
4089 for (UN j=0; j < indices.size(); j++){
4091 indices[j] = GO ( mapping2->getGlobalElement( T ) );
4093 indices[j] = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(j) ) );
4095 for (UN d=0; d<dim; d++) {
4096 GO row = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(i) ) + d );
4097 BTmat->insertGlobalValues( row, indices(), valueVec[d]() );
4103 if (callFillComplete) {
4104 Bmat->fillComplete( map1, map2 );
4105 BTmat->fillComplete( map2, map1 );
4111template <
class SC,
class LO,
class GO,
class NO>
4113 std::string FEType1,
4114 std::string FEType2,
4116 MatrixPtr_Type &Bmat,
4117 MatrixPtr_Type &BTmat,
4118 MapConstPtr_Type map1,
4119 MapConstPtr_Type map2,
4120 bool callFillComplete) {
4123 UN FEloc1 = checkFE(dim,FEType1);
4124 UN FEloc2 = checkFE(dim,FEType2);
4126 ElementsPtr_Type elements1 = domainVec_.at(FEloc1)->getElementsC();
4127 ElementsPtr_Type elements2 = domainVec_.at(FEloc2)->getElementsC();
4129 vec2D_dbl_ptr_Type pointsRep1 = domainVec_.at(FEloc1)->getPointsRepeated();
4131 MapConstPtr_Type mapping1 = domainVec_.at(FEloc1)->getMapRepeated();
4132 MapConstPtr_Type mapping2;
4134 if (FEType2 ==
"P0")
4135 mapping2 = domainVec_.at(FEloc2)->getElementMap();
4137 mapping2 = domainVec_.at(FEloc2)->getMapRepeated();
4139 vec3D_dbl_ptr_Type dPhi;
4140 vec2D_dbl_ptr_Type phi;
4141 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
4150 if (FEType2==
"P1-disc" && FEType1==
"Q2" )
4160 vec_dbl_Type v_i(dim);
4161 vec_dbl_Type v_j(dim);
4163 Teuchos::Array<GO> colIndex( 1, 0 );
4164 Teuchos::Array<GO> rowIndex( 1, 0 );
4165 Teuchos::Array<SC> value(1, 0.);
4167 for (UN T=0; T<elements1->numberElements(); T++) {
4170 detB = B.computeInverse(Binv);
4171 absDetB = std::fabs(detB);
4173 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4174 applyBTinv( dPhi, dPhiTrans, Binv );
4176 for (UN i=0; i < phi->at(0).size(); i++) {
4178 rowIndex[0] = GO ( mapping2->getGlobalElement( T ) );
4180 rowIndex[0] = GO ( mapping2->getGlobalElement( elements2->getElement(T).getNode(i) ) );
4182 for (UN j=0; j < dPhiTrans[0].size(); j++) {
4183 for (UN d=0; d<dim; d++){
4185 for (UN w=0; w<dPhiTrans.size(); w++)
4186 value[0] += weights->at(w) * phi->at(w)[i] * dPhiTrans[w][j][d];
4187 value[0] *= absDetB;
4188 colIndex[0] = GO ( dim * mapping1->getGlobalElement( elements1->getElement(T).getNode(j) ) + d );
4189 Bmat->insertGlobalValues( rowIndex[0], colIndex(), value() );
4190 BTmat->insertGlobalValues( colIndex[0], rowIndex(), value() );
4197 if (callFillComplete) {
4198 Bmat->fillComplete( map1, map2 );
4199 BTmat->fillComplete( map2, map1 );
4205template <
class SC,
class LO,
class GO,
class NO>
4209 bool callFillComplete){
4211 TEUCHOS_TEST_FOR_EXCEPTION(FEType !=
"P1" && FEType !=
"Q1",std::logic_error,
"Only implemented for P1, Q1.");
4212 UN FEloc = checkFE(dim,FEType);
4214 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4216 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4218 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4220 vec2D_dbl_ptr_Type phi;
4222 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
4232 vec_dbl_Type v_i(dim);
4233 vec_dbl_Type v_j(dim);
4239 refElementSize = 0.5;
4240 refElementScale = 1./9.;
4243 refElementSize = 1./6.;
4244 refElementScale = 1./16.;
4247 else if(FEType==
"Q1"){
4249 refElementScale=1./64;
4253 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Q1 Only implemented for 3D.");
4257 for (UN T=0; T<elements->numberElements(); T++) {
4260 detB = B.computeDet( );
4261 absDetB = std::fabs(detB);
4263 for (UN i=0; i < phi->at(0).size(); i++) {
4264 Teuchos::Array<SC> value( phi->at(0).size(), 0. );
4265 Teuchos::Array<GO> indices( phi->at(0).size(), 0 );
4266 for (UN j=0; j < value.size(); j++) {
4267 for (UN w=0; w<phi->size(); w++) {
4268 value[j] += weights->at(w) * (*phi)[w][i] * (*phi)[w][j];
4270 value[j] *= absDetB;
4271 value[j] -= refElementSize * absDetB * refElementScale;
4273 indices[j] = map->getGlobalElement( elements->getElement(T).getNode(j) );
4276 GO row = map->getGlobalElement( elements->getElement(T).getNode(i) );
4277 A->insertGlobalValues( row, indices(), value() );
4282 if (callFillComplete)
4288template <
class SC,
class LO,
class GO,
class NO>
4292 CoeffFuncDbl_Type func,
4294 bool callFillComplete)
4296 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
4297 int FEloc = this->checkFE(dim,FEType);
4299 DomainConstPtr_Type domain = domainVec_.at(FEloc);
4300 ElementsPtr_Type elements = domain->getElementsC();
4301 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
4302 MapConstPtr_Type map = domain->getMapRepeated();
4304 vec3D_dbl_ptr_Type dPhi;
4305 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(
new vec_dbl_Type(0));
4306 vec2D_dbl_ptr_Type quadPts;
4323 vec_dbl_ptr_Type dist = domain->getDistancesToInterface();
4326 double val, value1_j, value2_j , value1_i, value2_i;
4327 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
4329 double distance1, distance2, distance3;
4330 vec_dbl_Type distance_mean(1);
4331 for (
int T = 0; T < elements->numberElements(); T++)
4333 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4334 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4335 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4337 distance1 = dist->at(elements->getElement(T).getNode(0));
4338 distance2 = dist->at(elements->getElement(T).getNode(1));
4339 distance3 = dist->at(elements->getElement(T).getNode(2));
4341 distance_mean.at(0) = (distance1 + distance2 + distance3)/3.0;
4342 double funcvalue = func(&distance_mean.at(0),parameters);
4345 detB = B.computeInverse(Binv);
4346 absDetB = std::fabs(detB);
4349 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4350 applyBTinv( dPhi, dPhiTrans, Binv );
4352 for (
int i = 0; i < dPhi->at(0).size(); i++)
4354 Teuchos::Array<SC> value( 1, 0. );
4355 Teuchos::Array<GO> indices( 1, 0 );
4357 for (
int j = 0; j < dPhi->at(0).size(); j++)
4360 for (
int k = 0; k < dPhi->size(); k++)
4363 value1_j = dPhiTrans.at(k).at(j).at(0);
4364 value2_j = dPhiTrans.at(k).at(j).at(1);
4366 value1_i = dPhiTrans.at(k).at(i).at(0);
4367 value2_i = dPhiTrans.at(k).at(i).at(1);
4369 val = val + funcvalue * weightsDPhi->at(k) * ( value1_j*value1_i + value2_j*value2_i );
4371 val = absDetB * val;
4374 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4375 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4376 indices[0] = glob_j;
4379 A->insertGlobalValues(glob_i, indices(), value());
4381 indices[0] = glob_j;
4382 A->insertGlobalValues(glob_i+1, indices(), value());
4386 if (callFillComplete)
4393 double val, value1_j, value2_j ,value3_j, value1_i, value2_i ,value3_i;
4395 long long glob_i, glob_j;
4396 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
4398 double distance1, distance2, distance3, distance4;
4399 vec_dbl_Type distance_mean(1);
4400 for (
int T = 0; T < elements->numberElements(); T++)
4402 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4403 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4404 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4405 p4 = pointsRep->at(elements->getElement(T).getNode(3));
4407 distance1 = dist->at(elements->getElement(T).getNode(0));
4408 distance2 = dist->at(elements->getElement(T).getNode(1));
4409 distance3 = dist->at(elements->getElement(T).getNode(2));
4410 distance4 = dist->at(elements->getElement(T).getNode(3));
4412 distance_mean.at(0) = (distance1 + distance2 + distance3 + distance4)/4.0;
4413 double funcvalue = func(&distance_mean.at(0),parameters);
4416 detB = B.computeInverse(Binv);
4417 absDetB = std::fabs(detB);
4420 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4421 applyBTinv( dPhi, dPhiTrans, Binv );
4423 for (
int i = 0; i < dPhi->at(0).size(); i++)
4425 Teuchos::Array<SC> value( 1, 0. );
4426 Teuchos::Array<GO> indices( 1, 0 );
4428 for (
int j = 0; j < dPhi->at(0).size(); j++)
4431 for (
int k = 0; k < dPhi->size(); k++)
4433 value1_j = dPhiTrans.at(k).at(j).at(0);
4434 value2_j = dPhiTrans.at(k).at(j).at(1);
4435 value3_j = dPhiTrans.at(k).at(j).at(2);
4437 value1_i = dPhiTrans.at(k).at(i).at(0);
4438 value2_i = dPhiTrans.at(k).at(i).at(1);
4439 value3_i = dPhiTrans.at(k).at(i).at(2);
4441 val = val + funcvalue * weightsDPhi->at(k) * (value1_j*value1_i + value2_j*value2_i + value3_j*value3_i);
4443 val = absDetB * val;
4446 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4447 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4448 indices[0] = glob_j;
4449 A->insertGlobalValues(glob_i, indices(), value());
4451 indices[0] = glob_j;
4452 A->insertGlobalValues(glob_i+1, indices(), value());
4454 indices[0] = glob_j;
4455 A->insertGlobalValues(glob_i+2, indices(), value());
4460 if (callFillComplete)
4470template <
class SC,
class LO,
class GO,
class NO>
4474 CoeffFunc_Type func,
4476 bool callFillComplete)
4479 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
4480 int FEloc = this->checkFE(dim,FEType);
4482 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4483 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4484 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
4486 vec3D_dbl_ptr_Type dPhi;
4487 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(
new vec_dbl_Type(0));
4488 vec2D_dbl_ptr_Type quadPts;
4506 double v11, v12, v21, v22, value1_j, value2_j , value1_i, value2_i;
4507 double e_11_j_1,e_12_j_1,e_21_j_1,e_22_j_1;
4508 double e_11_j_2,e_12_j_2,e_21_j_2,e_22_j_2;
4509 double e_11_i_1,e_12_i_1,e_21_i_1,e_22_i_1;
4510 double e_11_i_2,e_12_i_2,e_21_i_2,e_22_i_2;
4519 long long glob_i, glob_j;
4520 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
4523 for (
int T = 0; T < elements->numberElements(); T++)
4525 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4526 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4527 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4530 detB = B.computeInverse(Binv);
4531 absDetB = std::fabs(detB);
4535 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4536 applyBTinv( dPhi, dPhiTrans, Binv );
4538 for (
int i = 0; i < dPhi->at(0).size(); i++)
4540 Teuchos::Array<SC> value11( 1, 0. );
4541 Teuchos::Array<SC> value12( 1, 0. );
4542 Teuchos::Array<SC> value21( 1, 0. );
4543 Teuchos::Array<SC> value22( 1, 0. );
4544 Teuchos::Array<GO> indices( 1, 0 );
4546 for (
int j=0; j < dPhi->at(0).size(); j++)
4548 v11 = 0.0;v12 = 0.0;v21 = 0.0;v22 = 0.0;
4549 for (
int k = 0; k < dPhi->size(); k++)
4554 for (
int r=0; r<2; r++) {
4555 xy[0] += B[0][r]*quadPts->at(k).at(r);
4556 xy[1] += B[1][r]*quadPts->at(k).at(r);
4561 value1_j = dPhiTrans.at(k).at(j).at(0);
4562 value2_j = dPhiTrans.at(k).at(j).at(1);
4564 value1_i = dPhiTrans.at(k).at(i).at(0);
4565 value2_i = dPhiTrans.at(k).at(i).at(1);
4567 tmpRes1[0][0] = value1_j;
4568 tmpRes1[0][1] = value2_j;
4572 tmpRes2[0][0] = value1_j;
4574 tmpRes2[1][0] = value2_j;
4577 tmpRes1.add(tmpRes2,e1j);
4579 e1i[0][0] = value1_i;
4580 e1i[0][1] = value2_i;
4585 tmpRes1[1][0] = value1_j;
4586 tmpRes1[1][1] = value2_j;
4589 tmpRes2[0][1] = value1_j;
4591 tmpRes2[1][1] = value2_j;
4593 tmpRes1.add(tmpRes2,e2j);
4595 e2i[1][0] = value1_i;
4596 e2i[1][1] = value2_i;
4598 double funcvalue = func(&xy.at(0),parameters);
4599 v11 = v11 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e1j);
4600 v12 = v12 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e2j);
4601 v21 = v21 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e1j);
4602 v22 = v22 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e2j);
4606 v11 = absDetB * v11;
4607 v12 = absDetB * v12;
4608 v21 = absDetB * v21;
4609 v22 = absDetB * v22;
4616 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4617 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4618 indices[0] = glob_j;
4620 A->insertGlobalValues(glob_i, indices(), value11());
4621 A->insertGlobalValues(glob_i+1, indices(), value21());
4623 indices[0] = glob_j;
4624 A->insertGlobalValues(glob_i, indices(), value12());
4625 A->insertGlobalValues(glob_i+1, indices(), value22());
4629 if (callFillComplete)
4636 double v11, v12, v13, v21, v22, v23, v31, v32, v33, value1_j, value2_j, value3_j , value1_i, value2_i, value3_i;
4645 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
4646 vec_dbl_Type xyz(3);
4648 for (
int T = 0; T < elements->numberElements(); T++)
4650 p1 = pointsRep->at(elements->getElement(T).getNode(0));
4651 p2 = pointsRep->at(elements->getElement(T).getNode(1));
4652 p3 = pointsRep->at(elements->getElement(T).getNode(2));
4653 p4 = pointsRep->at(elements->getElement(T).getNode(3));
4656 detB = B.computeInverse(Binv);
4657 absDetB = std::fabs(detB);
4660 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
4661 applyBTinv( dPhi, dPhiTrans, Binv );
4663 for (
int i = 0; i < dPhi->at(0).size(); i++)
4665 Teuchos::Array<SC> value11( 1, 0. );
4666 Teuchos::Array<SC> value12( 1, 0. );
4667 Teuchos::Array<SC> value13( 1, 0. );
4668 Teuchos::Array<SC> value21( 1, 0. );
4669 Teuchos::Array<SC> value22( 1, 0. );
4670 Teuchos::Array<SC> value23( 1, 0. );
4671 Teuchos::Array<SC> value31( 1, 0. );
4672 Teuchos::Array<SC> value32( 1, 0. );
4673 Teuchos::Array<SC> value33( 1, 0. );
4674 Teuchos::Array<GO> indices( 1, 0 );
4676 for (
int j = 0; j < dPhi->at(0).size(); j++)
4678 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;
4679 for (
int k = 0; k < dPhi->size(); k++)
4682 xyz[0]=0.; xyz[1]=0.; xyz[2]=0.;
4683 for (
int r = 0; r < 3; r++)
4685 xyz[0] += B[0][r]*quadPts->at(k).at(r);
4686 xyz[1] += B[1][r]*quadPts->at(k).at(r);
4687 xyz[2] += B[2][r]*quadPts->at(k).at(r);
4695 value1_j = dPhiTrans.at(k).at(j).at(0);
4696 value2_j = dPhiTrans.at(k).at(j).at(1);
4697 value3_j = dPhiTrans.at(k).at(j).at(2);
4700 value1_i = dPhiTrans.at(k).at(i).at(0);
4701 value2_i = dPhiTrans.at(k).at(i).at(1);
4702 value3_i = dPhiTrans.at(k).at(i).at(2);
4705 e1j[0][0] = 2.*value1_j;
4706 e1j[0][1] = value2_j;
4707 e1j[0][2] = value3_j;
4708 e1j[1][0] = value2_j;
4709 e1j[2][0] = value3_j;
4711 e1i[0][0] = value1_i;
4712 e1i[0][1] = value2_i;
4713 e1i[0][2] = value3_i;
4716 e2j[1][0] = value1_j;
4717 e2j[1][1] = 2.*value2_j;
4718 e2j[1][2] = value3_j;
4719 e2j[0][1] = value1_j;
4720 e2j[2][1] = value3_j;
4722 e2i[1][0] = value1_i;
4723 e2i[1][1] = value2_i;
4724 e2i[1][2] = value3_i;
4727 e3j[2][0] = value1_j;
4728 e3j[2][1] = value2_j;
4729 e3j[2][2] = 2.*value3_j;
4730 e3j[0][2] = value1_j;
4731 e3j[1][2] = value2_j;
4733 e3i[2][0] = value1_i;
4734 e3i[2][1] = value2_i;
4735 e3i[2][2] = value3_i;
4737 double funcvalue = func(&xyz.at(0),parameters);
4739 v11 = v11 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e1j);
4740 v12 = v12 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e2j);
4741 v13 = v13 + funcvalue * weightsDPhi->at(k) * e1i.innerProduct(e3j);
4743 v21 = v21 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e1j);
4744 v22 = v22 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e2j);
4745 v23 = v23 + funcvalue * weightsDPhi->at(k) * e2i.innerProduct(e3j);
4747 v31 = v31 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e1j);
4748 v32 = v32 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e2j);
4749 v33 = v33 + funcvalue * weightsDPhi->at(k) * e3i.innerProduct(e3j);
4753 v11 = absDetB * v11;
4754 v12 = absDetB * v12;
4755 v13 = absDetB * v13;
4756 v21 = absDetB * v21;
4757 v22 = absDetB * v22;
4758 v23 = absDetB * v23;
4759 v31 = absDetB * v31;
4760 v32 = absDetB * v32;
4761 v33 = absDetB * v33;
4773 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
4774 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
4775 indices[0] = glob_j;
4776 A->insertGlobalValues(glob_i, indices(), value11());
4777 A->insertGlobalValues(glob_i+1, indices(), value21());
4778 A->insertGlobalValues(glob_i+2, indices(), value31());
4781 indices[0] = glob_j;
4782 A->insertGlobalValues(glob_i, indices(), value12());
4783 A->insertGlobalValues(glob_i+1, indices(), value22());
4784 A->insertGlobalValues(glob_i+2, indices(), value32());
4787 indices[0] = glob_j;
4788 A->insertGlobalValues(glob_i, indices(), value13());
4789 A->insertGlobalValues(glob_i+1, indices(), value23());
4790 A->insertGlobalValues(glob_i+2, indices(), value33());
4794 if (callFillComplete)
4803template <
class SC,
class LO,
class GO,
class NO>
4804double FE<SC,LO,GO,NO>::assemblyAbsorbingBoundaryPaper(
int dim,
4806 MultiVectorPtr_Type f,
4807 MultiVectorPtr_Type u_rep,
4808 vec_dbl_Type flowRate_vec,
4809 std::vector<SC>& funcParameter,
4811 double areaOutlet_init,
4812 double areaOutlet_T,
4813 ParameterListPtr_Type params,
4816 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
4818 ElementsPtr_Type elementsPressure = domainVec_.at(FEloc+1)->getElementsC();
4820 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
4822 vec2D_dbl_ptr_Type phi;
4825 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
4830 vec2D_dbl_ptr_Type quadPoints;
4831 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
4835 double poissonRatio=params->sublist(
"Parameter Fluid").get(
"Poisson Ratio",0.49);
4836 int flagInlet = params->sublist(
"General").get(
"Flag Inlet Fluid", 4);
4837 int flagOutlet = params->sublist(
"General").get(
"Flag Outlet Fluid", 5);
4839 double normalScale = params->sublist(
"Parameter Fluid").get(
"Normal Scale",1.0);
4840 double E = params->sublist(
"Parameter Fluid").get(
"E",12.0);
4841 double wallThickness = params->sublist(
"Parameter Fluid").get(
"Wall thickness",0.0006);
4842 double density = params->sublist(
"Parameter Fluid").get(
"Density",1000.0);
4843 double p_ref_input = params->sublist(
"Parameter Fluid").get(
"Reference fluid pressure",10666.);
4845 double rampTime = params->sublist(
"Parameter Fluid").get(
"Max Ramp Time",0.1);
4846 double unsteadyStart = params->sublist(
"Parameter Fluid").get(
"Unsteady Start",0.2);
4847 double flowRateInput = params->sublist(
"Parameter Fluid").get(
"Flowrate",3.0);
4849 double bcRamp = params->sublist(
"Parameter Fluid").get(
"BC Ramp",0.1);
4857 vec_dbl_Type b(dim);
4859 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
4861 std::vector<double> valueFunc(dim);
4863 double flowRateOutlet=0.;
4864 double flowRateInlet=0.;
4866 this->assemblyFlowRate(dim, flowRateInlet, FEType , dim, flagInlet , u_rep);
4868 int isNeg = this->assemblyFlowRate(dim, flowRateOutlet, FEType , dim, flagOutlet , u_rep);
4870 double flowRateOutletAveraged = (flowRate_vec[0] + flowRate_vec[1]) / 2.;
4872 double areaOutlet = 0.;
4873 this->assemblyArea(dim, areaOutlet, flagOutlet);
4875 double areaInlet =0.;
4876 this->assemblyArea(dim, areaInlet, flagInlet);
4879 if(funcParameter[0] < unsteadyStart)
4880 beta = ((wallThickness* E)/(1.-pow(poissonRatio,2))) * (M_PI/areaOutlet_init ) ;
4882 beta = ((wallThickness* E)/(1.-pow(poissonRatio,2))) * (M_PI/areaOutlet_T ) ;
4885 funcParameter.push_back(p_ref_input);
4886 funcParameter.push_back(bcRamp);
4887 funcParameter.push_back(flagOutlet);
4888 SC* paramsFunc = &(funcParameter[0]);
4889 vec_dbl_Type x_tmp(dim,0.);
4890 paramsFunc[ funcParameter.size() - 1 ] =flagOutlet;
4891 paramsFunc[ 1 ] = p_ref_input;
4892 func( &x_tmp[0], &valueFunc[0], paramsFunc);
4893 double p_ref = valueFunc[0];
4894 if(funcParameter[0]+1e-12 >= unsteadyStart){
4895 p_ref = p_ref - std::pow( (std::sqrt(density)/(2*std::sqrt(2)) * flowRateInput/areaOutlet_T + std::sqrt(beta*std::sqrt(areaOutlet_T))),2) + beta*std::sqrt(areaOutlet_T);
4897 if(domainVec_.at(0)->getComm()->getRank()==0){
4898 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
4899 std::cout <<
" ---------------- Start of unsteady phase ---------------- " <<std::endl;
4900 std::cout <<
" Reference pressure adjusted from " << p_ref_input <<
" to " << p_ref <<std::endl;
4905 double flowRateUse = flowRateOutlet;
4906 if(params->sublist(
"Parameter Fluid").get(
"Average Flowrate",
false) )
4907 flowRateUse = flowRateOutletAveraged;
4912 double A_bar = 1./((std::sqrt(beta*std::sqrt(areaOutlet_init)+p_ref_input)-std::sqrt(beta*std::sqrt(areaOutlet_init)))*2.*std::sqrt(2.)*(1./std::sqrt(density))*(1./flowRateInput));
4915 if(funcParameter[0] < unsteadyStart)
4916 h_x= std::pow( (std::sqrt(density)/(2*std::sqrt(2)) * flowRateUse/A_bar + std::sqrt(beta*std::sqrt(areaOutlet_init))),2) - beta*std::sqrt(areaOutlet_init);
4918 h_x= std::pow( (std::sqrt(density)/(2*std::sqrt(2)) * flowRateUse/areaOutlet + std::sqrt(beta*std::sqrt(areaOutlet_T))),2) - beta*std::sqrt(areaOutlet_T) + p_ref;
4922 if(domainVec_.at(0)->getComm()->getRank()==0){
4923 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
4924 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
4925 std::cout <<
" Absorbing Boundary Condition " <<std::endl;
4926 std::cout <<
" Input p_ref: " << p_ref_input <<std::endl;
4927 std::cout <<
" Adjusted p_ref: " << p_ref <<std::endl;
4928 std::cout <<
" Unsteady start time_ " << unsteadyStart <<std::endl;
4929 std::cout <<
" Volmetric flow Inlet: " << flowRateInlet <<std::endl;
4930 std::cout <<
" Volmetric flow Outlet: " << flowRateOutlet <<std::endl;
4931 std::cout <<
" Averaged volmetric flow Outlet: " << flowRateOutletAveraged <<std::endl;
4932 std::cout <<
" beta per Input: " << beta <<std::endl;
4933 std::cout <<
" Area_init outlet: " << areaOutlet_init <<std::endl;
4934 std::cout <<
" Area_init outlet_T: " << areaOutlet_T <<std::endl;
4935 std::cout <<
" Area inlet: " << areaInlet <<std::endl;
4936 std::cout <<
" Area outlet: " << areaOutlet <<std::endl;
4937 std::cout <<
" A_bar: " << A_bar <<std::endl;
4938 std::cout <<
" Flowrate was negative: " << isNeg <<std::endl;
4939 std::cout <<
" Value h_x at outlet: " << h_x <<std::endl;
4940 std::cout <<
" --------------------------------------------------------- " <<std::endl;
4941 std::cout <<
" --------------------------------------------------------- " <<std::endl;
4945 for (UN T=0; T<elements->numberElements(); T++) {
4946 FiniteElement fe = elements->getElement( T );
4947 ElementsPtr_Type subEl = fe.getSubElements();
4948 for (
int surface=0; surface<fe.numSubElements(); surface++) {
4949 FiniteElement feSub = subEl->getElement( surface );
4950 if(subEl->getDimension() == dim-1 ){
4951 if(feSub.getFlag() == flagOutlet){
4952 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
4953 vec_int_Type nodeListP = elementsPressure->getElement(T).getSubElements()->getElement(surface).getVectorNodeListNonConst();
4954 int numNodes_T = nodeList.size();
4955 vec_dbl_Type solution_u = getSolution(nodeList, u_rep,dim);
4956 vec2D_dbl_Type nodes;
4957 nodes = getCoordinates(nodeList, pointsRep);
4959 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
4961 double norm_v_E = 1.;
4963 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
4964 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
4965 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
4970 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
4971 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
4972 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
4974 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
4975 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
4976 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
4978 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
4979 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
4980 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
4982 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
4990 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
4991 elScaling = B.computeScaling( );
4995 for (UN i=0; i < numNodes_T; i++) {
4998 Teuchos::Array<SC> value(0);
4999 value.resize( dim, 0. );
5001 for (UN w=0; w<phi->size(); w++) {
5002 for (
int j=0; j<dim; j++){
5003 value[j] += weights->at(w) *normalScale*v_E[j]/norm_v_E *h_x*(*phi)[w][i];
5008 for (
int j=0; j<value.size(); j++)
5009 valuesF[ dim * nodeList[ i ] + j ] += value[j] * elScaling;
5021template <
class SC,
class LO,
class GO,
class NO>
5022double FE<SC,LO,GO,NO>::assemblyAbsorbingBoundary(
int dim,
5024 MultiVectorPtr_Type f,
5025 MultiVectorPtr_Type u_rep,
5026 vec_dbl_Type flowRate_vec,
5027 std::vector<SC>& funcParameter,
5029 double areaOutlet_init,
5030 double areaOutlet_T,
5031 ParameterListPtr_Type params,
5034 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5036 ElementsPtr_Type elementsPressure = domainVec_.at(FEloc+1)->getElementsC();
5038 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5040 vec2D_dbl_ptr_Type phi;
5043 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
5045 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0);
5046 Helper::getPhi(phi, weights, dim-1, FEType, deg);
5048 vec2D_dbl_ptr_Type quadPoints;
5049 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
5050 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
5053 double poissonRatio=params->sublist(
"Parameter Fluid").get(
"Poisson Ratio",0.49);
5054 int flagInlet = params->sublist(
"General").get(
"Flag Inlet Fluid", 4);
5055 int flagOutlet = params->sublist(
"General").get(
"Flag Outlet Fluid", 5);
5057 double normalScale = params->sublist(
"Parameter Fluid").get(
"Normal Scale",1.0);
5059 double density = params->sublist(
"Parameter Fluid").get(
"Density",1.0);
5060 double p_ref_input = params->sublist(
"Parameter Fluid").get(
"Reference fluid pressure",10666.);
5062 double rampTime = params->sublist(
"Parameter Fluid").get(
"Max Ramp Time",0.1);
5063 double unsteadyStart = params->sublist(
"Parameter Fluid").get(
"Heart Beat Start",0.2);
5064 double flowRateInput = params->sublist(
"Parameter Fluid").get(
"Flowrate",3.0e-06);
5066 double bcRamp = params->sublist(
"Parameter Fluid").get(
"BC Ramp",0.1);
5070 SmallMatrix<SC> B(dim);
5071 SmallMatrix<SC> Binv(dim);
5074 vec_dbl_Type b(dim);
5076 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
5078 std::vector<double> valueFunc(dim);
5080 double flowRateOutlet=0.;
5081 double flowRateInlet=0.;
5083 this->assemblyFlowRate(dim, flowRateInlet, FEType , dim, flagInlet , u_rep);
5084 int isNeg = this->assemblyFlowRate(dim, flowRateOutlet, FEType , dim, flagOutlet , u_rep);
5086 double flowRateOutletAveraged = (flowRate_vec[0] + flowRate_vec[1]) / 2.;
5088 double areaOutlet = 0.;
5089 this->assemblyArea(dim, areaOutlet, flagOutlet);
5091 double areaInlet =0.;
5092 this->assemblyArea(dim, areaInlet, flagInlet);
5096 double E = params->sublist(
"Parameter Fluid").get(
"E",12.0);
5097 double wallThickness = params->sublist(
"Parameter Fluid").get(
"Wall thickness",0.0006);
5099 beta = ((wallThickness* E)/(1.-pow(poissonRatio,2))) * (M_PI/areaOutlet_init ) ;
5102 funcParameter.push_back(p_ref_input);
5103 funcParameter.push_back(bcRamp);
5104 funcParameter.push_back(flagOutlet);
5106 SC* paramsFunc = &(funcParameter[0]);
5107 vec_dbl_Type x_tmp(dim,0.);
5112 func( &x_tmp[0], &valueFunc[0], paramsFunc);
5113 double p_ref = valueFunc[0];
5119 double flowRateUse = flowRateOutlet;
5120 if(params->sublist(
"Parameter Fluid").get(
"Average Flowrate",
false) )
5121 flowRateUse = flowRateOutletAveraged;
5126 if(domainVec_.at(0)->getComm()->getRank()==0){
5127 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
5128 std::cout <<
" ---------------- computing p_ref ---------------- " <<std::endl;
5129 std::cout <<
" Reference pressure adjusted from " << p_ref_input <<
" to " << p_ref <<std::endl;
5133 double h_x = pow( (sqrt(density)/(2*sqrt(2)) * flowRateUse/areaOutlet + sqrt(beta*sqrt(areaOutlet_init))),2) - beta*sqrt(areaOutlet_init)+p_ref;
5137 if(domainVec_.at(0)->getComm()->getRank()==0){
5138 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
5139 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
5140 std::cout <<
" Absorbing Boundary Condition " <<std::endl;
5141 std::cout <<
" Input p_ref: " << p_ref_input <<std::endl;
5142 std::cout <<
" Adjusted p_ref: " << p_ref <<std::endl;
5143 std::cout <<
" Volmetric flow Inlet: " << flowRateInlet <<std::endl;
5144 std::cout <<
" Volmetric flow Outlet: " << flowRateOutlet <<std::endl;
5145 std::cout <<
" Averaged volmetric flow Outlet: " << flowRateOutletAveraged <<std::endl;
5146 std::cout <<
" beta per Input: " << beta <<std::endl;
5147 std::cout <<
" Area_init outlet: " << areaOutlet_init <<std::endl;
5148 std::cout <<
" Area inlet: " << areaInlet <<std::endl;
5149 std::cout <<
" Area outlet: " << areaOutlet <<std::endl;
5150 std::cout <<
" Value h_x at outlet: " << h_x <<std::endl;
5151 std::cout <<
" --------------------------------------------------------- " <<std::endl;
5152 std::cout <<
" --------------------------------------------------------- " <<std::endl;
5156 for (UN T=0; T<elements->numberElements(); T++) {
5157 FiniteElement fe = elements->getElement( T );
5158 ElementsPtr_Type subEl = fe.getSubElements();
5159 for (
int surface=0; surface<fe.numSubElements(); surface++) {
5160 FiniteElement feSub = subEl->getElement( surface );
5161 if(subEl->getDimension() == dim-1 ){
5162 if(feSub.getFlag() == flagOutlet){
5163 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5164 vec_int_Type nodeListP = elementsPressure->getElement(T).getSubElements()->getElement(surface).getVectorNodeListNonConst();
5165 int numNodes_T = nodeList.size();
5166 vec_dbl_Type solution_u = getSolution(nodeList, u_rep,dim);
5167 vec2D_dbl_Type nodes;
5168 nodes = getCoordinates(nodeList, pointsRep);
5170 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5172 double norm_v_E = 1.;
5174 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5175 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
5176 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
5181 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
5182 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5183 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
5185 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
5186 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
5187 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
5189 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
5190 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
5191 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
5193 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
5198 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
5199 elScaling = B.computeScaling( );
5201 for (UN i=0; i < numNodes_T; i++) {
5204 Teuchos::Array<SC> value(0);
5205 value.resize( dim, 0. );
5207 for (UN w=0; w<phi->size(); w++) {
5208 for (
int j=0; j<dim; j++){
5209 value[j] += weights->at(w) *normalScale*v_E[j]/norm_v_E *h_x*(*phi)[w][i];
5214 for (
int j=0; j<value.size(); j++)
5215 valuesF[ dim * nodeList[ i ] + j ] += value[j] * elScaling;
5228template <
class SC,
class LO,
class GO,
class NO>
5229double FE<SC,LO,GO,NO>::assemblyAbsorbingResistanceBoundary(
int dim,
5231 MultiVectorPtr_Type f,
5232 MultiVectorPtr_Type u_rep,
5233 vec_dbl_Type flowRate_vec,
5234 std::vector<SC>& funcParameter,
5236 double areaOutlet_init,
5237 ParameterListPtr_Type params,
5240 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5242 ElementsPtr_Type elementsPressure = domainVec_.at(FEloc+1)->getElementsC();
5244 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5246 vec2D_dbl_ptr_Type phi;
5249 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
5251 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0);
5252 Helper::getPhi(phi, weights, dim-1, FEType, deg);
5254 vec2D_dbl_ptr_Type quadPoints;
5255 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
5256 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
5259 double poissonRatio=params->sublist(
"Parameter Fluid").get(
"Poisson Ratio",0.49);
5260 double viscosity=params->sublist(
"Parameter Fluid").get(
"Viscosity",1.0e-06);
5261 int flagInlet = params->sublist(
"General").get(
"Flag Inlet Fluid", 4);
5262 int flagOutlet = params->sublist(
"General").get(
"Flag Outlet Fluid", 5);
5264 double normalScale = params->sublist(
"Parameter Fluid").get(
"Normal Scale",1.0);
5265 double E = params->sublist(
"Parameter Fluid").get(
"E",12.0);
5266 double wallThickness = params->sublist(
"Parameter Fluid").get(
"Wall thickness",0.001);
5267 double density = params->sublist(
"Parameter Fluid").get(
"Density",1000.0);
5268 double p_ref_input = params->sublist(
"Parameter Fluid").get(
"Reference fluid pressure",8000.);
5269 double resistanceRamp = params->sublist(
"Parameter Fluid").get(
"Resistance Ramp",2.);
5270 double resistance = params->sublist(
"Parameter Fluid").get(
"Resistance",1.0);
5273 SmallMatrix<SC> B(dim);
5274 SmallMatrix<SC> Binv(dim);
5277 vec_dbl_Type b(dim);
5279 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
5281 std::vector<double> valueFunc(dim);
5283 double flowRateOutlet=0.;
5284 double flowRateInlet=0.;
5286 this->assemblyFlowRate(dim, flowRateInlet, FEType , dim, flagInlet , u_rep);
5287 this->assemblyFlowRate(dim, flowRateOutlet, FEType , dim, flagOutlet , u_rep);
5289 double flowRateOutletAveraged = (flowRate_vec[0] + flowRate_vec[1]) / 2.;
5291 double areaOutlet = 0.;
5292 this->assemblyArea(dim, areaOutlet, flagOutlet);
5294 double areaInlet =0.;
5295 this->assemblyArea(dim, areaInlet, flagInlet);
5297 double beta = (((wallThickness* E)/(1-pow(poissonRatio,2))) * M_PI/areaOutlet_init ) *sqrt(areaOutlet_init);
5299 SC* paramsFunc = &(funcParameter[0]);
5300 vec_dbl_Type x_tmp(dim,0.);
5301 paramsFunc[ funcParameter.size() - 1 ] =flagOutlet;
5305 double flowRateUse = flowRateOutlet;
5306 if(params->sublist(
"Parameter Fluid").get(
"Average Flowrate",
false) )
5307 flowRateUse = flowRateOutletAveraged;
5310 if(paramsFunc[0] < resistanceRamp){
5312 p_ref = flowRateUse*resistance;
5316 paramsFunc[ 1 ] = p_ref_input;
5317 func( &x_tmp[0], &valueFunc[0], paramsFunc);
5319 p_ref = valueFunc[0];
5323 double h_x = pow( (sqrt(density)/(2*sqrt(2)) * flowRateUse/areaOutlet + sqrt(beta)),2) - beta + p_ref;
5326 if(domainVec_.at(0)->getComm()->getRank()==0){
5327 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
5328 std::cout <<
" ---------------------------------------------------------- " <<std::endl;
5329 std::cout <<
" Absorbing Boundary Condition " <<std::endl;
5330 std::cout <<
" p_ref: " << p_ref <<std::endl;
5331 std::cout <<
" Volmetric flow Inlet: " << flowRateInlet <<std::endl;
5332 std::cout <<
" Volmetric flow Outlet: " << flowRateOutlet <<std::endl;
5333 std::cout <<
" Averaged volmetric flow Outlet: " << flowRateOutletAveraged <<std::endl;
5334 std::cout <<
" beta*sqrt(A_0) per Input: " << beta <<std::endl;
5335 std::cout <<
" Area_init outlet: " << areaOutlet_init <<std::endl;
5336 std::cout <<
" Area inlet: " << areaInlet <<std::endl;
5337 std::cout <<
" Area outlet: " << areaOutlet <<std::endl;
5338 std::cout <<
" Value h_x at outlet: " << h_x <<std::endl;
5339 std::cout <<
" --------------------------------------------------------- " <<std::endl;
5340 std::cout <<
" --------------------------------------------------------- " <<std::endl;
5344 for (UN T=0; T<elements->numberElements(); T++) {
5345 FiniteElement fe = elements->getElement( T );
5346 ElementsPtr_Type subEl = fe.getSubElements();
5347 for (
int surface=0; surface<fe.numSubElements(); surface++) {
5348 FiniteElement feSub = subEl->getElement( surface );
5349 if(subEl->getDimension() == dim-1 ){
5350 if(feSub.getFlag() == flagOutlet){
5351 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5352 vec_int_Type nodeListP = elementsPressure->getElement(T).getSubElements()->getElement(surface).getVectorNodeListNonConst();
5353 int numNodes_T = nodeList.size();
5354 vec_dbl_Type solution_u = getSolution(nodeList, u_rep,dim);
5355 vec2D_dbl_Type nodes;
5356 nodes = getCoordinates(nodeList, pointsRep);
5358 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5360 double norm_v_E = 1.;
5362 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5363 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
5364 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
5369 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
5370 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5371 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
5373 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
5374 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
5375 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
5377 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
5378 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
5379 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
5381 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
5389 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
5390 elScaling = B.computeScaling( );
5394 for (UN i=0; i < numNodes_T; i++) {
5397 Teuchos::Array<SC> value(0);
5398 value.resize( dim, 0. );
5400 for (UN w=0; w<phi->size(); w++) {
5401 for (
int j=0; j<dim; j++){
5402 value[j] += weights->at(w) *normalScale*v_E[j]/norm_v_E *h_x*(*phi)[w][i];
5407 for (
int j=0; j<value.size(); j++)
5408 valuesF[ dim * nodeList[ i ] + j ] += value[j] * elScaling;
5421template <
class SC,
class LO,
class GO,
class NO>
5422double FE<SC,LO,GO,NO>::assemblyResistanceBoundary(
int dim,
5424 MultiVectorPtr_Type f,
5425 MultiVectorPtr_Type u_rep,
5426 vec_dbl_Type flowRate_vec,
5427 std::vector<SC>& funcParameter,
5429 ParameterListPtr_Type params,
5432 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5434 ElementsPtr_Type elementsPressure = domainVec_.at(FEloc+1)->getElementsC();
5436 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5438 vec2D_dbl_ptr_Type phi;
5439 vec2D_dbl_ptr_Type phi1;
5441 vec3D_dbl_ptr_Type dPhi;
5443 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
5444 vec_dbl_ptr_Type weights1 = Teuchos::rcp(
new vec_dbl_Type(0));
5446 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0);
5447 Helper::getDPhi(dPhi, weights, dim, FEType, deg);
5448 Helper::getPhi(phi, weights, dim-1, FEType, deg);
5449 Helper::getPhi(phi1, weights1, dim-1, FEType, 2);
5451 vec2D_dbl_ptr_Type quadPoints;
5452 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
5453 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
5456 double viscosity=params->sublist(
"Parameter").get(
"Viscosity",0.49);
5457 int flagInlet = params->sublist(
"General").get(
"Flag Inlet Fluid", 4);
5458 int flagOutlet = params->sublist(
"General").get(
"Flag Outlet Fluid", 5);
5460 double normalScale = params->sublist(
"Parameter Fluid").get(
"Normal Scale",1.0);
5461 double resistance = params->sublist(
"Parameter Fluid").get(
"Resistance",1.0);
5462 double bcRamp = params->sublist(
"Parameter Fluid").get(
"BC Ramp",0.1);
5464 double referencePressure = params->sublist(
"Parameter Fluid").get(
"Reference fluid pressure",11.99e1);
5468 SmallMatrix<SC> B(dim);
5469 SmallMatrix<SC> Binv(dim);
5472 vec_dbl_Type b(dim);
5474 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
5476 std::vector<double> valueFunc(dim);
5479 funcParameter.push_back(resistance);
5480 funcParameter.push_back(bcRamp);
5481 funcParameter.push_back(flagOutlet);
5483 SC* paramsFunc = &(funcParameter[0]);
5484 double flowRateInlet=0.;
5485 double flowRateOutlet=0.;
5486 this->assemblyFlowRate(dim, flowRateInlet, FEType , dim, flagInlet , u_rep);
5487 int isNeg = this->assemblyFlowRate(dim, flowRateOutlet, FEType , dim, flagOutlet , u_rep);
5489 double resistanceRef = referencePressure/flowRateInlet;
5491 double flowRateOutletAveraged = (flowRate_vec[0] + flowRate_vec[1]) / 2.;
5493 vec_dbl_Type x_tmp(dim,0.);
5496 func( &x_tmp[0], &valueFunc[0], paramsFunc);
5498 if(domainVec_.at(0)->getComm()->getRank()==0){
5499 std::cout <<
" ---------------------------------------------------------- " << std::endl;
5500 std::cout <<
" ---------------------------------------------------------- " << std::endl;
5501 std::cout <<
" Resistance Boundary Condition " << std::endl;
5502 std::cout <<
" Volmetric flow Inlet: " << flowRateInlet << std::endl;
5503 std::cout <<
" Volmetric flow Outlet: " << flowRateOutlet << std::endl;
5504 std::cout <<
" Averaged volmetric flow Outlet: " << flowRateOutletAveraged << std::endl;
5505 std::cout <<
" Resistance per Input: " << valueFunc[0] << std::endl;
5506 std::cout <<
" Assumed reference pressure at outlet " << referencePressure<< std::endl;
5507 std::cout <<
" Implicit pressure at outlet with p=R*Q: " << flowRateOutlet*valueFunc[0] << std::endl;
5508 std::cout <<
" Resistance based on (referencePressure)/flowRateInlet at this point would be: " << resistanceRef << std::endl;
5509 std::cout <<
" --------------------------------------------------------- " << std::endl;
5510 std::cout <<
" --------------------------------------------------------- " << std::endl;
5514 double flowRateUse = flowRateOutlet;
5515 if(params->sublist(
"Parameter Fluid").get(
"Average Flowrate",
false) )
5516 flowRateUse = flowRateOutletAveraged;
5521 double p_out = flowRateUse*valueFunc[0];
5524 for (UN T=0; T<elements->numberElements(); T++) {
5525 FiniteElement fe = elements->getElement( T );
5526 ElementsPtr_Type subEl = fe.getSubElements();
5527 for (
int surface=0; surface<fe.numSubElements(); surface++) {
5528 FiniteElement feSub = subEl->getElement( surface );
5529 if(subEl->getDimension() == dim-1 ){
5532 if(feSub.getFlag() == flagOutlet){
5533 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5534 vec_int_Type nodeListP = elementsPressure->getElement(T).getSubElements()->getElement(surface).getVectorNodeListNonConst();
5535 int numNodes_T = nodeList.size();
5536 vec_dbl_Type solution_u = getSolution(nodeList, u_rep,dim);
5537 vec2D_dbl_Type nodes;
5538 nodes = getCoordinates(nodeList, pointsRep);
5540 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5542 double norm_v_E = 1.;
5544 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5545 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
5546 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
5551 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
5552 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5553 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
5555 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
5556 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
5557 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
5559 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
5560 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
5561 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
5563 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
5572 vec_dbl_Type quadWeights(dim);
5573 quadWeights[0] = 1/6.;
5574 quadWeights[1] = 1/6.;
5575 quadWeights[2] = 1/6.;
5576 vec2D_dbl_Type quadPoints(quadWeights.size(), vec_dbl_Type(dim));
5578 vec_int_Type kn1= elements->getElement(T).getVectorNodeListNonConst();
5580 vec2D_dbl_Type quadPointsT1(quadWeights.size(),vec_dbl_Type(dim));
5581 quadPointsT1.push_back({0.5,0.5,0.0});
5582 quadPointsT1.push_back({0.0,0.5,0.0});
5583 quadPointsT1.push_back({0.5,0.0,0.0});
5587 SmallMatrix<SC> B1(dim);
5588 SmallMatrix<SC> Binv1(dim);
5592 for (
int s=0; s<dim; s++) {
5594 for (
int t=0; t<dim; t++) {
5595 B1[t][s] = pointsRep->at(index).at(t) -pointsRep->at(index0).at(t);
5599 detB1 = B1.computeInverse(Binv1);
5600 detB1 = std::fabs(detB1);
5603 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
5604 elScaling = B.computeScaling( );
5608 for (UN i=0; i < numNodes_T; i++) {
5611 Teuchos::Array<SC> value(0);
5612 value.resize( dim, 0. );
5614 for (UN w=0; w<phi->size(); w++) {
5615 for (
int d=0; d<dim; d++){
5616 value[d] += weights->at(w) *normalScale*v_E[d]/norm_v_E *flowRateUse*valueFunc[0]*(*phi)[w][i];
5621 for (
int d=0; d<dim; d++)
5622 valuesF[ dim * nodeList[ i ] + d ] += value[d] * elScaling;
5626 vec_dbl_Type valueSecondComp(dim,0.);
5628 for (UN t=0; t < numNodes_T; t++) {
5629 Teuchos::Array<SC> value( dim, 0. );
5630 for(
int l=0; l< quadWeights.size(); l++){
5631 vec_dbl_Type deriPhi1( dim,0.0) ;
5632 vec_dbl_ptr_Type valuePhi(
new vec_dbl_Type(dim,0.0));
5634 auto it1 = find( kn1.begin(), kn1.end() ,nodeList[t] );
5635 int id_in_element = distance( kn1.begin() , it1 );
5637 Helper::gradPhi(dim,2,id_in_element,quadPointsT1[l],valuePhi);
5638 for (
int j=0; j<3; j++) {
5639 deriPhi1[j] = valuePhi->at(j);
5642 vec_dbl_Type deriPhiT1(dim,0.);
5643 for(
int q=0; q<dim; q++){
5644 for(
int s=0; s< dim ; s++)
5645 deriPhiT1[q] += (deriPhi1[s]*Binv1[s][q]);
5649 for (UN d=0; d<dim; d++) {
5650 value[d] += quadWeights[l] *solution_u[t*dim+d] * deriPhi1[d]* v_E[d]/norm_v_E * (*phi)[l][t];
5654 for (
int j=0; j<value.size(); j++)
5655 valuesF[ dim * nodeList[ t ] + j ] -= normalScale*value[j] *elScaling*viscosity;
5669template <
class SC,
class LO,
class GO,
class NO>
5670void FE<SC,LO,GO,NO>::assemblyArea(
int dim,
5675 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5677 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5679 int inletFlag=inflowFlag;
5681 double areaSurface=0.;
5684 for (UN T=0; T<elements->numberElements(); T++) {
5685 FiniteElement fe = elements->getElement( T );
5686 ElementsPtr_Type subEl = fe.getSubElements();
5687 for (
int surface=0; surface<fe.numSubElements(); surface++) {
5688 FiniteElement feSub = subEl->getElement( surface );
5689 if(subEl->getDimension() == dim-1 ){
5690 if(feSub.getFlag() == inletFlag){
5691 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5692 int numNodes_T = nodeList.size();
5693 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5695 double norm_v_E = 1.;
5697 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5698 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
5699 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
5700 areaSurface += norm_v_E;
5705 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
5706 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5707 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
5709 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
5710 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
5711 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
5713 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
5714 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
5715 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
5717 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
5720 areaSurface += norm_v_E*0.5;
5733 reduceAll<int, double> (*domainVec_.at(0)->getComm(), REDUCE_SUM, areaSurface, outArg (areaSurface));
5739template <
class SC,
class LO,
class GO,
class NO>
5740int FE<SC,LO,GO,NO>::assemblyFlowRate(
int dim,
5741 double &flowRateParabolic,
5745 MultiVectorPtr_Type solution_rep,
5748 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5750 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5752 vec2D_dbl_ptr_Type phi;
5754 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
5756 Helper::getPhi(phi, weights, dim-1, FEType, 2);
5758 vec2D_dbl_ptr_Type quadPoints;
5759 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
5760 Helper::getQuadratureValues(dim-1, 2, quadPoints, w, FEType);
5763 int inletFlag=inflowFlag;
5767 vec_dbl_Type b(dim);
5768 SmallMatrix<SC> B(dim);
5769 SmallMatrix<SC> Binv(dim);
5773 double flowRateInlet=0.;
5775 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
5777 Teuchos::ArrayRCP< const SC > uArray = solution_rep->getData(0);
5779 for (UN T=0; T<elements->numberElements(); T++) {
5780 FiniteElement fe = elements->getElement( T );
5781 ElementsPtr_Type subEl = fe.getSubElements();
5782 for (
int surface=0; surface<fe.numSubElements(); surface++) {
5783 FiniteElement feSub = subEl->getElement( surface );
5784 if(subEl->getDimension() == dim-1 ){
5785 if(feSub.getFlag() == inletFlag){
5786 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5787 int numNodes_T = nodeList.size();
5788 vec_dbl_Type solution_u = getSolution(nodeList, solution_rep,dofs);
5791 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5793 double norm_v_E = 1.;
5795 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5796 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
5797 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2));
5802 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
5803 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
5804 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
5806 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
5807 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
5808 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
5810 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
5811 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
5812 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
5814 norm_v_E = sqrt(pow(v_E[0],2)+pow(v_E[1],2)+pow(v_E[2],2));
5821 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
5822 elScaling = B.computeScaling( );
5824 Teuchos::Array<SC> value(0);
5825 value.resize( numNodes_T, 0. );
5837 for (UN i=0; i < numNodes_T; i++) {
5839 for (UN w=0; w<phi->size(); w++) {
5840 for (
int j=0; j<dim; j++){
5842 value[i] += weights->at(w) *v_E[j]/norm_v_E *solution_u[i]*(*phi)[w][i];
5845 LO index = dim * i + j;
5846 value[i] += weights->at(w) *v_E[j]/norm_v_E *solution_u[index]*(*phi)[w][i];
5851 flowRateInlet += value[i] * elScaling;
5860 reduceAll<int, double> (*domainVec_.at(0)->getComm(), REDUCE_SUM, flowRateInlet, outArg (flowRateInlet));
5865 if(flowRateInlet <0)
5867 flowRateParabolic = fabs(flowRateInlet);
5874template <
class SC,
class LO,
class GO,
class NO>
5875void FE<SC,LO,GO,NO>::assemblyAverageVelocity(
int dim,
5876 double &averageVelocity,
5880 MultiVectorPtr_Type solution_rep,
5883 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5885 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5887 vec2D_dbl_ptr_Type phi;
5889 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
5891 Helper::getPhi(phi, weights, dim-1, FEType, 2);
5893 vec2D_dbl_ptr_Type quadPoints;
5894 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
5895 Helper::getQuadratureValues(dim-1, 2, quadPoints, w, FEType);
5899 this->assemblyArea(dim, area, flag);
5902 vec_dbl_Type b(dim);
5903 SmallMatrix<SC> B(dim);
5904 SmallMatrix<SC> Binv(dim);
5910 vec2D_dbl_Type uLoc( dim, vec_dbl_Type( weights->size() , -1. ) );
5912 Teuchos::ArrayRCP< const SC > uArray = solution_rep->getData(0);
5914 for (UN T=0; T<elements->numberElements(); T++) {
5915 FiniteElement fe = elements->getElement( T );
5916 ElementsPtr_Type subEl = fe.getSubElements();
5917 for(
int surface=0; surface<fe.numSubElements(); surface++) {
5918 FiniteElement feSub = subEl->getElement( surface );
5919 if(subEl->getDimension() == dim-1 ){
5920 if(feSub.getFlag() == flag){
5921 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
5922 int numNodes_T = nodeList.size();
5923 vec_dbl_Type solution_u = getSolution(nodeList, solution_rep,dofs);
5925 vec_dbl_Type p1(dim),p2(dim),v_E(dim,1.);
5929 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
5930 elScaling = B.computeScaling( );
5932 Teuchos::Array<SC> value(0);
5933 value.resize( numNodes_T, 0. );
5935 for (UN i=0; i < numNodes_T; i++) {
5937 for (UN w=0; w<phi->size(); w++) {
5938 for (
int j=0; j<dim; j++){
5940 value[i] += weights->at(w)*solution_u[i]*(*phi)[w][i];
5943 LO index = dim * i + j;
5944 value[i] += weights->at(w)*solution_u[index]*(*phi)[w][i];
5949 velocity += value[i] * elScaling;
5955 reduceAll<int, double> (*domainVec_.at(0)->getComm(), REDUCE_SUM, velocity, outArg (velocity));
5956 velocity = velocity/area;
5957 std::cout <<
" Average Flowvelocity "<< velocity <<
" ####### " <<std::endl;
5959 averageVelocity = velocity;
5964template <
class SC,
class LO,
class GO,
class NO>
5970 bool callFillComplete)
5972 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
5973 int FEloc = this->checkFE(dim,FEType);
5976 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
5977 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
5978 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
5980 vec3D_dbl_ptr_Type dPhi;
5981 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(
new vec_dbl_Type(0));
5982 vec2D_dbl_ptr_Type quadPts;
6004 double res_trace_i, res_trace_j;
6009 double v11, v12, v21, v22;
6011 vec_dbl_Type p1(2,0.0), p2(2,0.0), p3(2,0.0);
6015 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim);
6017 for (
int T = 0; T < elements->numberElements(); T++)
6020 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6021 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6022 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6026 detB = B.computeInverse(Binv);
6027 absDetB = std::fabs(detB);
6031 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6032 applyBTinv( dPhi, dPhiTrans, Binv );
6034 for (
int i = 0; i < dPhi->at(0).size(); i++)
6036 Teuchos::Array<SC> value11( 1, 0. );
6037 Teuchos::Array<SC> value12( 1, 0. );
6038 Teuchos::Array<SC> value21( 1, 0. );
6039 Teuchos::Array<SC> value22( 1, 0. );
6040 Teuchos::Array<GO> indices( 1, 0 );
6042 for (
int j = 0; j < dPhi->at(0).size(); j++)
6044 v11 = 0.0; v12 = 0.0; v21 = 0.0; v22 = 0.0;
6045 for (
int k = 0; k < dPhi->size(); k++)
6055 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0);
6056 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1);
6062 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0);
6063 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1);
6068 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res);
6069 epsilonValuesMat1_i.trace(res_trace_i);
6070 epsilonValuesMat1_j.trace(res_trace_j);
6071 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6073 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res);
6074 epsilonValuesMat1_i.trace(res_trace_i);
6075 epsilonValuesMat2_j.trace(res_trace_j);
6076 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6078 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res);
6079 epsilonValuesMat2_i.trace(res_trace_i);
6080 epsilonValuesMat1_j.trace(res_trace_j);
6081 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6083 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res);
6084 epsilonValuesMat2_i.trace(res_trace_i);
6085 epsilonValuesMat2_j.trace(res_trace_j);
6086 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6091 v11 = absDetB * v11;
6092 v12 = absDetB * v12;
6093 v21 = absDetB * v21;
6094 v22 = absDetB * v22;
6102 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6103 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6104 indices[0] = glob_j;
6105 A->insertGlobalValues(glob_i, indices(), value11());
6106 A->insertGlobalValues(glob_i+1, indices(), value21());
6108 indices[0] = glob_j;
6109 A->insertGlobalValues(glob_i, indices(), value12());
6110 A->insertGlobalValues(glob_i+1, indices(), value22());
6114 if (callFillComplete)
6122 double v11, v12, v13, v21, v22, v23, v31, v32, v33;
6124 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
6125 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim), epsilonValuesMat3_i(dim),
6126 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim), epsilonValuesMat3_j(dim);
6128 for (
int T = 0; T < elements->numberElements(); T++)
6130 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6131 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6132 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6133 p4 = pointsRep->at(elements->getElement(T).getNode(3));
6136 detB = B.computeInverse(Binv);
6137 absDetB = std::fabs(detB);
6140 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6141 applyBTinv( dPhi, dPhiTrans, Binv );
6143 for (
int i = 0; i < dPhi->at(0).size(); i++)
6145 Teuchos::Array<SC> value11( 1, 0. );
6146 Teuchos::Array<SC> value12( 1, 0. );
6147 Teuchos::Array<SC> value13( 1, 0. );
6148 Teuchos::Array<SC> value21( 1, 0. );
6149 Teuchos::Array<SC> value22( 1, 0. );
6150 Teuchos::Array<SC> value23( 1, 0. );
6151 Teuchos::Array<SC> value31( 1, 0. );
6152 Teuchos::Array<SC> value32( 1, 0. );
6153 Teuchos::Array<SC> value33( 1, 0. );
6154 Teuchos::Array<GO> indices( 1, 0 );
6156 for (
int j = 0; j < dPhi->at(0).size(); j++)
6158 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;
6159 for (
int k = 0; k < dPhi->size(); k++)
6164 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0);
6165 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1);
6166 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat3_i, 2);
6171 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0);
6172 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1);
6173 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat3_j, 2);
6175 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res);
6176 epsilonValuesMat1_i.trace(res_trace_i);
6177 epsilonValuesMat1_j.trace(res_trace_j);
6178 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6180 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res);
6181 epsilonValuesMat1_i.trace(res_trace_i);
6182 epsilonValuesMat2_j.trace(res_trace_j);
6183 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6185 epsilonValuesMat1_i.innerProduct(epsilonValuesMat3_j, res);
6186 epsilonValuesMat1_i.trace(res_trace_i);
6187 epsilonValuesMat3_j.trace(res_trace_j);
6188 v13 = v13 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6190 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res);
6191 epsilonValuesMat2_i.trace(res_trace_i);
6192 epsilonValuesMat1_j.trace(res_trace_j);
6193 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6195 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res);
6196 epsilonValuesMat2_i.trace(res_trace_i);
6197 epsilonValuesMat2_j.trace(res_trace_j);
6198 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6200 epsilonValuesMat2_i.innerProduct(epsilonValuesMat3_j, res);
6201 epsilonValuesMat2_i.trace(res_trace_i);
6202 epsilonValuesMat3_j.trace(res_trace_j);
6203 v23 = v23 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6205 epsilonValuesMat3_i.innerProduct(epsilonValuesMat1_j, res);
6206 epsilonValuesMat3_i.trace(res_trace_i);
6207 epsilonValuesMat1_j.trace(res_trace_j);
6208 v31 = v31 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6210 epsilonValuesMat3_i.innerProduct(epsilonValuesMat2_j, res);
6211 epsilonValuesMat3_i.trace(res_trace_i);
6212 epsilonValuesMat2_j.trace(res_trace_j);
6213 v32 = v32 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6215 epsilonValuesMat3_i.innerProduct(epsilonValuesMat3_j, res);
6216 epsilonValuesMat3_i.trace(res_trace_i);
6217 epsilonValuesMat3_j.trace(res_trace_j);
6218 v33 = v33 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6221 v11 = absDetB * v11;
6222 v12 = absDetB * v12;
6223 v13 = absDetB * v13;
6224 v21 = absDetB * v21;
6225 v22 = absDetB * v22;
6226 v23 = absDetB * v23;
6227 v31 = absDetB * v31;
6228 v32 = absDetB * v32;
6229 v33 = absDetB * v33;
6241 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6242 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6243 indices[0] = glob_j;
6244 A->insertGlobalValues(glob_i, indices(), value11());
6245 A->insertGlobalValues(glob_i+1, indices(), value21());
6246 A->insertGlobalValues(glob_i+2, indices(), value31());
6248 indices[0] = glob_j;
6249 A->insertGlobalValues(glob_i, indices(), value12());
6250 A->insertGlobalValues(glob_i+1, indices(), value22());
6251 A->insertGlobalValues(glob_i+2, indices(), value32());
6253 indices[0] = glob_j;
6254 A->insertGlobalValues(glob_i, indices(), value13());
6255 A->insertGlobalValues(glob_i+1, indices(), value23());
6256 A->insertGlobalValues(glob_i+2, indices(), value33());
6260 if (callFillComplete)
6268template <
class SC,
class LO,
class GO,
class NO>
6269void FE<SC,LO,GO,NO>::determineEMod(std::string FEType, MultiVectorPtr_Type solution,MultiVectorPtr_Type &eModVec, DomainConstPtr_Type domain, ParameterListPtr_Type params){
6272 ElementsPtr_Type elements = domain->getElementsC();
6274 int dim = domain->getDimension();
6275 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
6279 Teuchos::ArrayRCP< const SC > uArray = solution->getData(0);
6280 Teuchos::ArrayRCP< SC > eModVecA = eModVec->getDataNonConst(0);
6282 double E0 = params->sublist(
"Parameter Solid").get(
"E",3.0e+6);
6283 double E1 = params->sublist(
"Parameter Solid").get(
"E1",3.0e+5);
6284 double c1 = params->sublist(
"Parameter Solid").get(
"c1",1.0);
6286 double eModMin = E0;
6288 int nodesElement = elements->getElement(0).getVectorNodeList().size();
6289 for (UN T=0; T<elements->numberElements(); T++) {
6297 for(
int i=0; i< nodesElement;i++){
6298 LO index = elements->getElement(T).getNode(i) ;
6299 uLoc += 1./nodesElement*uArray[index];
6302 eModVecA[T] = E0-(E0-E1)*(uLoc/(uLoc+c1));
6303 if(eModVecA[T] > eModMax )
6304 eModMax = eModVecA[T];
6305 if(eModVecA[T] < eModMin)
6306 eModMin = eModVecA[T];
6308 Teuchos::reduceAll<int, double> (*(domain->getComm()), Teuchos::REDUCE_MIN, eModMin, Teuchos::outArg (eModMin));
6309 Teuchos::reduceAll<int, double> (*(domain->getComm()), Teuchos::REDUCE_MAX, eModMax, Teuchos::outArg (eModMax));
6311 if(domain->getComm()->getRank()==0)
6312 std::cout <<
" ################# eMOD Min: " << eModMin <<
" \t eModMax: " << eModMax<<
" ############# " << std::endl;
6319template <
class SC,
class LO,
class GO,
class NO>
6323 MultiVectorPtr_Type eModVec,
6325 bool callFillComplete)
6327 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
6328 int FEloc = this->checkFE(dim,FEType);
6331 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
6332 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
6333 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
6335 vec3D_dbl_ptr_Type dPhi;
6336 vec_dbl_ptr_Type weightsDPhi = Teuchos::rcp(
new vec_dbl_Type(0));
6337 vec2D_dbl_ptr_Type quadPts;
6355 double res_trace_i, res_trace_j;
6357 Teuchos::ArrayRCP< const SC > E = eModVec->getData(0);
6364 double v11, v12, v21, v22;
6366 vec_dbl_Type p1(2,0.0), p2(2,0.0), p3(2,0.0);
6370 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim);
6372 for (
int T = 0; T < elements->numberElements(); T++)
6375 lambda = E[T]* nu / ((1.+nu)*(1.-2.*nu));
6376 mu = E[T] / (2.*(1.+nu));
6379 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6380 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6381 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6385 detB = B.computeInverse(Binv);
6386 absDetB = std::fabs(detB);
6390 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6391 applyBTinv( dPhi, dPhiTrans, Binv );
6393 for (
int i = 0; i < dPhi->at(0).size(); i++)
6395 Teuchos::Array<SC> value11( 1, 0. );
6396 Teuchos::Array<SC> value12( 1, 0. );
6397 Teuchos::Array<SC> value21( 1, 0. );
6398 Teuchos::Array<SC> value22( 1, 0. );
6399 Teuchos::Array<GO> indices( 1, 0 );
6401 for (
int j = 0; j < dPhi->at(0).size(); j++)
6403 v11 = 0.0; v12 = 0.0; v21 = 0.0; v22 = 0.0;
6404 for (
int k = 0; k < dPhi->size(); k++)
6414 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0);
6415 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1);
6421 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0);
6422 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1);
6427 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res);
6428 epsilonValuesMat1_i.trace(res_trace_i);
6429 epsilonValuesMat1_j.trace(res_trace_j);
6430 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6432 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res);
6433 epsilonValuesMat1_i.trace(res_trace_i);
6434 epsilonValuesMat2_j.trace(res_trace_j);
6435 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6437 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res);
6438 epsilonValuesMat2_i.trace(res_trace_i);
6439 epsilonValuesMat1_j.trace(res_trace_j);
6440 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6442 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res);
6443 epsilonValuesMat2_i.trace(res_trace_i);
6444 epsilonValuesMat2_j.trace(res_trace_j);
6445 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6450 v11 = absDetB * v11;
6451 v12 = absDetB * v12;
6452 v21 = absDetB * v21;
6453 v22 = absDetB * v22;
6461 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6462 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6463 indices[0] = glob_j;
6464 A->insertGlobalValues(glob_i, indices(), value11());
6465 A->insertGlobalValues(glob_i+1, indices(), value21());
6467 indices[0] = glob_j;
6468 A->insertGlobalValues(glob_i, indices(), value12());
6469 A->insertGlobalValues(glob_i+1, indices(), value22());
6473 if (callFillComplete)
6481 double v11, v12, v13, v21, v22, v23, v31, v32, v33;
6483 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
6484 SmallMatrix<double> epsilonValuesMat1_i(dim), epsilonValuesMat2_i(dim), epsilonValuesMat3_i(dim),
6485 epsilonValuesMat1_j(dim), epsilonValuesMat2_j(dim), epsilonValuesMat3_j(dim);
6487 for (
int T = 0; T < elements->numberElements(); T++)
6489 lambda = E[T]* nu / ((1.+nu)*(1.-2.*nu));
6490 mu = E[T] / (2.*(1.+nu));
6492 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6493 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6494 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6495 p4 = pointsRep->at(elements->getElement(T).getNode(3));
6498 detB = B.computeInverse(Binv);
6499 absDetB = std::fabs(detB);
6502 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6503 applyBTinv( dPhi, dPhiTrans, Binv );
6505 for (
int i = 0; i < dPhi->at(0).size(); i++)
6508 Teuchos::Array<SC> value11( 1, 0. );
6509 Teuchos::Array<SC> value12( 1, 0. );
6510 Teuchos::Array<SC> value13( 1, 0. );
6511 Teuchos::Array<SC> value21( 1, 0. );
6512 Teuchos::Array<SC> value22( 1, 0. );
6513 Teuchos::Array<SC> value23( 1, 0. );
6514 Teuchos::Array<SC> value31( 1, 0. );
6515 Teuchos::Array<SC> value32( 1, 0. );
6516 Teuchos::Array<SC> value33( 1, 0. );
6517 Teuchos::Array<GO> indices( 1, 0 );
6519 for (
int j = 0; j < dPhi->at(0).size(); j++)
6521 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;
6522 for (
int k = 0; k < dPhi->size(); k++)
6527 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat1_i, 0);
6528 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat2_i, 1);
6529 epsilonTensor( dPhiTrans.at(k).at(i), epsilonValuesMat3_i, 2);
6534 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat1_j, 0);
6535 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat2_j, 1);
6536 epsilonTensor( dPhiTrans.at(k).at(j), epsilonValuesMat3_j, 2);
6538 epsilonValuesMat1_i.innerProduct(epsilonValuesMat1_j, res);
6539 epsilonValuesMat1_i.trace(res_trace_i);
6540 epsilonValuesMat1_j.trace(res_trace_j);
6541 v11 = v11 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6543 epsilonValuesMat1_i.innerProduct(epsilonValuesMat2_j, res);
6544 epsilonValuesMat1_i.trace(res_trace_i);
6545 epsilonValuesMat2_j.trace(res_trace_j);
6546 v12 = v12 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6548 epsilonValuesMat1_i.innerProduct(epsilonValuesMat3_j, res);
6549 epsilonValuesMat1_i.trace(res_trace_i);
6550 epsilonValuesMat3_j.trace(res_trace_j);
6551 v13 = v13 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6553 epsilonValuesMat2_i.innerProduct(epsilonValuesMat1_j, res);
6554 epsilonValuesMat2_i.trace(res_trace_i);
6555 epsilonValuesMat1_j.trace(res_trace_j);
6556 v21 = v21 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6558 epsilonValuesMat2_i.innerProduct(epsilonValuesMat2_j, res);
6559 epsilonValuesMat2_i.trace(res_trace_i);
6560 epsilonValuesMat2_j.trace(res_trace_j);
6561 v22 = v22 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6563 epsilonValuesMat2_i.innerProduct(epsilonValuesMat3_j, res);
6564 epsilonValuesMat2_i.trace(res_trace_i);
6565 epsilonValuesMat3_j.trace(res_trace_j);
6566 v23 = v23 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6568 epsilonValuesMat3_i.innerProduct(epsilonValuesMat1_j, res);
6569 epsilonValuesMat3_i.trace(res_trace_i);
6570 epsilonValuesMat1_j.trace(res_trace_j);
6571 v31 = v31 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6573 epsilonValuesMat3_i.innerProduct(epsilonValuesMat2_j, res);
6574 epsilonValuesMat3_i.trace(res_trace_i);
6575 epsilonValuesMat2_j.trace(res_trace_j);
6576 v32 = v32 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6578 epsilonValuesMat3_i.innerProduct(epsilonValuesMat3_j, res);
6579 epsilonValuesMat3_i.trace(res_trace_i);
6580 epsilonValuesMat3_j.trace(res_trace_j);
6581 v33 = v33 + weightsDPhi->at(k)*(2*mu*res + lambda*res_trace_j*res_trace_i);
6584 v11 = absDetB * v11;
6585 v12 = absDetB * v12;
6586 v13 = absDetB * v13;
6587 v21 = absDetB * v21;
6588 v22 = absDetB * v22;
6589 v23 = absDetB * v23;
6590 v31 = absDetB * v31;
6591 v32 = absDetB * v32;
6592 v33 = absDetB * v33;
6604 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6605 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6606 indices[0] = glob_j;
6607 A->insertGlobalValues(glob_i, indices(), value11());
6608 A->insertGlobalValues(glob_i+1, indices(), value21());
6609 A->insertGlobalValues(glob_i+2, indices(), value31());
6611 indices[0] = glob_j;
6612 A->insertGlobalValues(glob_i, indices(), value12());
6613 A->insertGlobalValues(glob_i+1, indices(), value22());
6614 A->insertGlobalValues(glob_i+2, indices(), value32());
6616 indices[0] = glob_j;
6617 A->insertGlobalValues(glob_i, indices(), value13());
6618 A->insertGlobalValues(glob_i+1, indices(), value23());
6619 A->insertGlobalValues(glob_i+2, indices(), value33());
6623 if (callFillComplete)
6631template <
class SC,
class LO,
class GO,
class NO>
6635 MultiVectorPtr_Type w,
6636 bool callFillComplete)
6639 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
6640 int FEloc = this->checkFE(dim,FEType);
6642 DomainConstPtr_Type domain = domainVec_.at(FEloc);
6643 ElementsPtr_Type elements = domain->getElementsC();
6644 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
6645 MapConstPtr_Type map = domain->getMapRepeated();
6647 vec3D_dbl_ptr_Type dPhi;
6648 vec2D_dbl_ptr_Type phi;
6649 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
6650 vec2D_dbl_ptr_Type quadPts;
6667 Teuchos::ArrayRCP< const SC > wArray = w->getData(0);
6672 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
6674 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
6675 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
6676 vec2D_dbl_Type divergenz(1, vec_dbl_Type(weights->size(), -1.));
6678 for (
int T = 0; T < elements->numberElements(); T++)
6680 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6681 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6682 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6685 detB = B.computeInverse(Binv);
6686 absDetB = std::fabs(detB);
6689 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6690 applyBTinv( dPhi, dPhiTrans, Binv );
6694 for(
int k = 0; k < dPhiTrans.size(); k++)
6698 for(
int i = 0; i < dPhiTrans[0].size(); i++)
6700 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
6701 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
6702 w11[0][k] += wArray[index1] * dPhiTrans[k][i][0];
6703 w22[0][k] += wArray[index2] * dPhiTrans[k][i][1];
6713 for(
int k = 0; k < dPhiTrans.size(); k++)
6715 divergenz[0][k] = w11[0][k] + w22[0][k];
6723 for (
int i = 0; i < dPhi->at(0).size(); i++)
6725 Teuchos::Array<SC> value( 1, 0. );
6726 Teuchos::Array<GO> indices( 1, 0 );
6728 for (
int j = 0; j < dPhi->at(0).size(); j++)
6731 for (
int k = 0; k < dPhi->size(); k++)
6733 val = val + divergenz[0][k] * weights->at(k) * (*phi)[k][i] * (*phi)[k][j];
6735 val = absDetB * val;
6743 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6744 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6745 indices[0] = glob_j;
6747 A->insertGlobalValues(glob_i, indices(), value());
6749 indices[0] = glob_j;
6750 A->insertGlobalValues(glob_i+1, indices(), value());
6754 if (callFillComplete)
6764 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
6766 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
6767 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
6768 vec2D_dbl_Type w33(1, vec_dbl_Type(weights->size(), -1.));
6769 vec2D_dbl_Type divergenz(1, vec_dbl_Type(weights->size(), -1.));
6771 for (
int T = 0; T < elements->numberElements(); T++)
6773 p1 = pointsRep->at(elements->getElement(T).getNode(0));
6774 p2 = pointsRep->at(elements->getElement(T).getNode(1));
6775 p3 = pointsRep->at(elements->getElement(T).getNode(2));
6776 p4 = pointsRep->at(elements->getElement(T).getNode(3));
6779 detB = B.computeInverse(Binv);
6780 absDetB = std::fabs(detB);
6783 vec3D_dbl_Type dPhiTrans( dPhi->size(), vec2D_dbl_Type( dPhi->at(0).size(), vec_dbl_Type(dim,0.) ) );
6784 applyBTinv( dPhi, dPhiTrans, Binv );
6788 for(
int k = 0; k < dPhiTrans.size(); k++)
6793 for(
int i = 0; i < dPhiTrans[0].size(); i++)
6795 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
6796 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
6797 LO index3 = dim * elements->getElement(T).getNode(i) + 2;
6798 w11[0][k] += wArray[index1] * dPhiTrans[k][i][0];
6799 w22[0][k] += wArray[index2] * dPhiTrans[k][i][1];
6800 w33[0][k] += wArray[index3] * dPhiTrans[k][i][2];
6804 for(
int k = 0; k < dPhiTrans.size(); k++)
6806 divergenz[0][k] = w11[0][k] + w22[0][k] + w33[0][k];
6809 for (
int i = 0; i < dPhi->at(0).size(); i++)
6811 Teuchos::Array<SC> value( 1, 0. );
6812 Teuchos::Array<GO> indices( 1, 0 );
6814 for (
int j = 0; j < dPhi->at(0).size(); j++)
6817 for (
int k = 0; k < dPhi->size(); k++)
6819 val = val + divergenz[0][k] * weights->at(k) * (*phi)[k][i] * (*phi)[k][j];
6821 val = absDetB * val;
6824 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
6825 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
6826 indices[0] = glob_j;
6827 A->insertGlobalValues(glob_i, indices(), value());
6829 indices[0] = glob_j;
6830 A->insertGlobalValues(glob_i+1, indices(), value());
6832 indices[0] = glob_j;
6833 A->insertGlobalValues(glob_i+2, indices(), value());
6838 if (callFillComplete)
6845template <
class SC,
class LO,
class GO,
class NO>
6846void FE<SC,LO,GO,NO>::assemblyDummyCoupling(
int dim,
6850 bool callFillComplete)
6852 DomainConstPtr_Type domain = domainVec_.at(FEloc);
6854 MapConstPtr_Type mapInterfaceVecField = domain->getInterfaceMapVecFieldUnique();
6855 MapConstPtr_Type mapGlobalInterfaceVecField = domain->getGlobalInterfaceMapVecFieldUnique();
6857 MapConstPtr_Type mapFieldPartial = domain->getGlobalInterfaceMapVecFieldPartial();
6859 Teuchos::Array<SC> value( 1, 0. );
6861 Teuchos::Array<GO> indices( 1, 0 );
6863 GO dofGlobal, dofLocal;
6865 for(
int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++)
6867 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
6868 if ( mapFieldPartial->getLocalElement( dofGlobal ) == Teuchos::OrdinalTraits<LO>::invalid() ) {
6870 dofGlobal = mapInterfaceVecField->getGlobalElement( k );
6871 indices[0] = dofGlobal;
6872 C->insertGlobalValues(dofGlobal, indices(), value());
6876 if (callFillComplete)
6877 C->fillComplete(mapInterfaceVecField, mapInterfaceVecField);
6881template <
class SC,
class LO,
class GO,
class NO>
6882void FE<SC,LO,GO,NO>::assemblyFSICoupling(
int dim,
6885 MatrixPtr_Type &C_T,
6888 MapConstPtr_Type map1,
6889 MapConstPtr_Type map2,
6890 bool callFillComplete)
6894 DomainConstPtr_Type domain1 = domainVec_.at(FEloc1);
6896 MapConstPtr_Type mapInterfaceVecField = domain1->getInterfaceMapVecFieldUnique();
6898 MapConstPtr_Type mapGlobalInterfaceVecField;
6899 MapConstPtr_Type mapFieldPartial;
6900 if (FEloc1!=FEloc2){
6901 mapFieldPartial = domain1->getOtherGlobalInterfaceMapVecFieldPartial();
6902 mapGlobalInterfaceVecField = domain1->getOtherGlobalInterfaceMapVecFieldUnique();
6905 mapFieldPartial = domain1->getGlobalInterfaceMapVecFieldPartial();
6906 mapGlobalInterfaceVecField = domain1->getGlobalInterfaceMapVecFieldUnique();
6909 Teuchos::Array<SC> value( 1, 0. );
6911 Teuchos::Array<GO> indices( 1, 0 );
6913 GO dofGlobal, dofLocal;
6914 if (mapFieldPartial.is_null()) {
6915 for(
int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++)
6918 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
6919 dofLocal = mapInterfaceVecField->getGlobalElement(k);
6921 indices[0] = dofLocal;
6922 C_T->insertGlobalValues(dofGlobal, indices(), value());
6923 indices[0] = dofGlobal;
6924 C->insertGlobalValues(dofLocal, indices(), value());
6929 for(
int k = 0; k < mapGlobalInterfaceVecField->getNodeNumElements(); k++) {
6930 dofGlobal = mapGlobalInterfaceVecField->getGlobalElement(k);
6931 if ( mapFieldPartial->getLocalElement( dofGlobal ) != Teuchos::OrdinalTraits<LO>::invalid() ) {
6933 dofLocal = mapInterfaceVecField->getGlobalElement(k);
6935 indices[0] = dofLocal;
6936 C_T->insertGlobalValues(dofGlobal, indices(), value());
6937 indices[0] = dofGlobal;
6938 C->insertGlobalValues(dofLocal, indices(), value());
6943 if (callFillComplete)
6947 C_T->fillComplete(map1, map2);
6948 C->fillComplete(map2, map1);
6953template <
class SC,
class LO,
class GO,
class NO>
6954void FE<SC,LO,GO,NO>::assemblyGeometryCoupling(
int dim,
6958 MapConstPtr_Type map1,
6959 MapConstPtr_Type map2,
6960 MapConstPtr_Type map3,
6961 bool callFillComplete)
6964 DomainConstPtr_Type domain = domainVec_.at(FEloc);
6966 MapConstPtr_Type mapInt = domain->getGlobalInterfaceMapVecFieldUnique();
6967 MapConstPtr_Type mapOtherInt = domain->getOtherGlobalInterfaceMapVecFieldUnique();
6968 MapConstPtr_Type mapPartInt = domain->getGlobalInterfaceMapVecFieldPartial();
6969 MapConstPtr_Type mapOtherPartInt = domain->getOtherGlobalInterfaceMapVecFieldPartial();
6970 Teuchos::Array<SC> value( 1, 0. );
6972 Teuchos::Array<GO> indices( 1, 0 );
6975 if (mapPartInt.is_null()) {
6976 for(
int k = 0; k < mapInt->getNodeNumElements(); k++){
6977 dofRow = mapInt->getGlobalElement(k);
6978 indices[0] = mapOtherInt->getGlobalElement(k);
6979 C->insertGlobalValues(dofRow, indices(), value());
6983 for(
int k = 0; k < mapPartInt->getNodeNumElements(); k++){
6984 dofRow = mapPartInt->getGlobalElement(k);
6985 indices[0] = mapOtherPartInt->getGlobalElement(k);
6986 C->insertGlobalValues(dofRow, indices(), value());
6989 if (callFillComplete)
6992 C->fillComplete(map2, map3);
6997template <
class SC,
class LO,
class GO,
class NO>
6998void FE<SC,LO,GO,NO>::assemblyShapeDerivativeVelocity(
int dim,
6999 std::string FEType1,
7000 std::string FEType2,
7003 MultiVectorPtr_Type u,
7004 MultiVectorPtr_Type w,
7005 MultiVectorPtr_Type p,
7009 bool callFillComplete)
7013 DomainConstPtr_Type domain = domainVec_.at(FEloc);
7014 ElementsPtr_Type elements = domain->getElementsC();
7015 vec2D_dbl_ptr_Type pointsRep = domain->getPointsRepeated();
7016 MapConstPtr_Type map = domain->getMapRepeated();
7018 vec3D_dbl_ptr_Type dPhiU;
7019 vec2D_dbl_ptr_Type phiU;
7020 vec2D_dbl_ptr_Type phiP;
7021 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
7022 vec2D_dbl_ptr_Type quadPts;
7025 UN extraDeg = 2*Helper::determineDegree( dim, FEType1, Helper::Deriv1);
7026 UN deg = 2*Helper::determineDegree( dim, FEType1, Helper::Deriv0) + extraDeg;
7028 Helper::getDPhi(dPhiU, weights, dim, FEType1, deg);
7029 Helper::getPhi(phiU, weights, dim, FEType1, deg);
7030 Helper::getPhi(phiP, weights, dim, FEType2, deg);
7031 Helper::getQuadratureValues(dim, deg, quadPts, weights,FEType1);
7036 SmallMatrix<SC> B(dim);
7037 SmallMatrix<SC> Binv(dim);
7041 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
7042 Teuchos::ArrayRCP< const SC > wArray = w->getData(0);
7043 Teuchos::ArrayRCP< const SC > pArray = p->getData(0);
7047 double val11, val12, val21, val22;
7048 double valDK1_11, valDK1_12, valDK1_21, valDK1_22;
7049 double valDK2_11, valDK2_12, valDK2_21, valDK2_22;
7050 double valDN_11, valDN_12, valDN_21, valDN_22;
7051 double valDW_11, valDW_12, valDW_21, valDW_22;
7052 double valDP_11, valDP_12, valDP_21, valDP_22;
7053 double valDM_11, valDM_12, valDM_21, valDM_22;
7054 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
7059 vec2D_dbl_Type u1Loc(1, vec_dbl_Type(weights->size(), -1.));
7060 vec2D_dbl_Type u2Loc(1, vec_dbl_Type(weights->size(), -1.));
7061 vec2D_dbl_Type w1Loc(1, vec_dbl_Type(weights->size(), -1.));
7062 vec2D_dbl_Type w2Loc(1, vec_dbl_Type(weights->size(), -1.));
7063 vec2D_dbl_Type pLoc(1, vec_dbl_Type(weights->size(), -1.));
7064 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
7065 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
7066 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
7067 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
7068 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
7069 vec2D_dbl_Type w12(1, vec_dbl_Type(weights->size(), -1.));
7070 vec2D_dbl_Type w21(1, vec_dbl_Type(weights->size(), -1.));
7071 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
7072 vec2D_dbl_Type sigma11(1, vec_dbl_Type(weights->size(), -1.));
7073 vec2D_dbl_Type sigma12(1, vec_dbl_Type(weights->size(), -1.));
7074 vec2D_dbl_Type sigma21(1, vec_dbl_Type(weights->size(), -1.));
7075 vec2D_dbl_Type sigma22(1, vec_dbl_Type(weights->size(), -1.));
7077 for (
int T = 0; T < elements->numberElements(); T++)
7079 p1 = pointsRep->at(elements->getElement(T).getNode(0));
7080 p2 = pointsRep->at(elements->getElement(T).getNode(1));
7081 p3 = pointsRep->at(elements->getElement(T).getNode(2));
7083 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType1);
7084 detB = B.computeInverse(Binv);
7085 absDetB = std::fabs(detB);
7088 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
7089 applyBTinv( dPhiU, dPhiTransU, Binv );
7092 for(
int k = 0; k < phiU->size(); k++)
7098 for(
int i = 0; i < phiU->at(0).size(); i++)
7100 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
7101 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
7102 u1Loc[0][k] += uArray[index1] * phiU->at(k).at(i);
7103 u2Loc[0][k] += uArray[index2] * phiU->at(k).at(i);
7104 w1Loc[0][k] += wArray[index1] * phiU->at(k).at(i);
7105 w2Loc[0][k] += wArray[index2] * phiU->at(k).at(i);
7112 for(
int k = 0; k < phiP->size(); k++)
7115 for(
int i = 0; i < phiP->at(0).size(); i++)
7119 LO index = elements->getElement(T).getNode(i) + 0;
7120 pLoc[0][k] += pArray[index] * phiP->at(k).at(i);
7127 for(
int k = 0; k < dPhiTransU.size(); k++)
7137 for(
int i = 0; i < dPhiTransU[0].size(); i++)
7139 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
7140 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
7141 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
7142 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
7143 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
7144 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
7145 w11[0][k] += wArray[index1] * dPhiTransU[k][i][0];
7146 w12[0][k] += wArray[index1] * dPhiTransU[k][i][1];
7147 w21[0][k] += wArray[index2] * dPhiTransU[k][i][0];
7148 w22[0][k] += wArray[index2] * dPhiTransU[k][i][1];
7155 for(
int k = 0; k < dPhiTransU.size(); k++)
7157 sigma11[0][k] = rho * nu * (u11[0][k] + u11[0][k]) - pLoc[0][k];
7158 sigma12[0][k] = rho * nu * (u12[0][k] + u21[0][k]);
7159 sigma21[0][k] = rho * nu * (u21[0][k] + u12[0][k]);
7160 sigma22[0][k] = rho * nu * (u22[0][k] + u22[0][k]) - pLoc[0][k];
7164 for (
int i = 0; i < dPhiU->at(0).size(); i++)
7166 Teuchos::Array<SC> value11( 1, 0. );
7167 Teuchos::Array<SC> value12( 1, 0. );
7168 Teuchos::Array<SC> value21( 1, 0. );
7169 Teuchos::Array<SC> value22( 1, 0. );
7170 Teuchos::Array<GO> indices( 1, 0 );
7172 for (
int j = 0; j < dPhiU->at(0).size(); j++)
7210 for (
int k = 0; k < dPhiU->size(); k++)
7213 valDK1_11 = valDK1_11 + weights->at(k) *
7214 ( 2 * u11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7215 u11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
7216 u21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7217 valDK1_12 = valDK1_12 + weights->at(k) *
7218 ( 2 * u12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7219 u12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
7220 u22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7221 valDK1_21 = valDK1_21 + weights->at(k) *
7222 ( u11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7223 u21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7224 2 * u21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] );
7225 valDK1_22 = valDK1_22 + weights->at(k) *
7226 ( u12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7227 u22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7228 2 * u22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] );
7231 valDK2_11 = valDK2_11 + weights->at(k) *
7232 ( -sigma12[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7233 sigma12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7234 valDK2_12 = valDK2_12 + weights->at(k) *
7235 ( sigma11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7236 -sigma11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7237 valDK2_21 = valDK2_21 + weights->at(k) *
7238 ( -sigma22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7239 sigma22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7240 valDK2_22 = valDK2_22 + weights->at(k) *
7241 ( sigma21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7242 -sigma21[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] );
7245 valDN_11 = valDN_11 + weights->at(k) *
7246 ( -(u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][1] * u11[0][k] * phiU->at(k).at(i) +
7247 (u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][0] * u12[0][k] * phiU->at(k).at(i) );
7248 valDN_12 = valDN_12 + weights->at(k) *
7249 ( (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][1] * u11[0][k] * phiU->at(k).at(i) -
7250 (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][0] * u12[0][k] * phiU->at(k).at(i) );
7251 valDN_21 = valDN_21 + weights->at(k) *
7252 ( -(u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][1] * u21[0][k] * phiU->at(k).at(i) +
7253 (u2Loc[0][k] - w2Loc[0][k]) * dPhiTransU[k][j][0] * u22[0][k] * phiU->at(k).at(i) );
7254 valDN_22 = valDN_22 + weights->at(k) *
7255 ( (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][1] * u21[0][k] * phiU->at(k).at(i) -
7256 (u1Loc[0][k] - w1Loc[0][k]) * dPhiTransU[k][j][0] * u22[0][k] * phiU->at(k).at(i) );
7259 valDW_11 = valDW_11 + weights->at(k) *
7260 ( u11[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7261 valDW_12 = valDW_12 + weights->at(k) *
7262 ( u12[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7263 valDW_21 = valDW_21 + weights->at(k) *
7264 ( u21[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7265 valDW_22 = valDW_22 + weights->at(k) *
7266 ( u22[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7269 valDP_11 = valDP_11 + weights->at(k) *
7270 ( ( -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] ) * u1Loc[0][k] * phiU->at(k).at(i) );
7271 valDP_12 = valDP_12 + weights->at(k) *
7272 ( ( w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] ) * u1Loc[0][k] * phiU->at(k).at(i) );
7273 valDP_21 = valDP_21 + weights->at(k) *
7274 ( ( -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] ) * u2Loc[0][k] * phiU->at(k).at(i) );
7275 valDP_22 = valDP_22 + weights->at(k) *
7276 ( ( w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] ) * u2Loc[0][k] * phiU->at(k).at(i) );
7279 valDM_11 = valDM_11 + weights->at(k) *
7280 ( dPhiTransU[k][j][0] * u1Loc[0][k] * phiU->at(k).at(i) );
7281 valDM_12 = valDM_12 + weights->at(k) *
7282 ( dPhiTransU[k][j][1] * u1Loc[0][k] * phiU->at(k).at(i) );
7283 valDM_21 = valDM_21 + weights->at(k) *
7284 ( dPhiTransU[k][j][0] * u2Loc[0][k] * phiU->at(k).at(i) );
7285 valDM_22 = valDM_22 + weights->at(k) *
7286 ( dPhiTransU[k][j][1] * u2Loc[0][k] * phiU->at(k).at(i) );
7289 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;
7290 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;
7291 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;
7292 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;
7294 val11 = absDetB * val11;
7295 val12 = absDetB * val12;
7296 val21 = absDetB * val21;
7297 val22 = absDetB * val22;
7304 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
7305 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
7306 indices[0] = glob_j;
7308 D->insertGlobalValues(glob_i, indices(), value11());
7309 D->insertGlobalValues(glob_i+1, indices(), value21());
7311 indices[0] = glob_j;
7312 D->insertGlobalValues(glob_i, indices(), value12());
7313 D->insertGlobalValues(glob_i+1, indices(), value22());
7317 if (callFillComplete)
7324 double val11, val12, val13, val21, val22, val23, val31, val32, val33;
7325 double valDK1_11, valDK1_12, valDK1_13, valDK1_21, valDK1_22, valDK1_23, valDK1_31, valDK1_32, valDK1_33;
7326 double valDK2_11, valDK2_12, valDK2_13, valDK2_21, valDK2_22, valDK2_23, valDK2_31, valDK2_32, valDK2_33;
7327 double valDN_11, valDN_12, valDN_13, valDN_21, valDN_22, valDN_23, valDN_31, valDN_32, valDN_33;
7328 double valDW_11, valDW_12, valDW_13, valDW_21, valDW_22, valDW_23, valDW_31, valDW_32, valDW_33;
7329 double valDP_11, valDP_12, valDP_13, valDP_21, valDP_22, valDP_23, valDP_31, valDP_32, valDP_33;
7330 double valDM_11, valDM_12, valDM_13, valDM_21, valDM_22, valDM_23, valDM_31, valDM_32, valDM_33;
7331 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
7336 vec2D_dbl_Type u1Loc(1, vec_dbl_Type(weights->size(), -1.));
7337 vec2D_dbl_Type u2Loc(1, vec_dbl_Type(weights->size(), -1.));
7338 vec2D_dbl_Type u3Loc(1, vec_dbl_Type(weights->size(), -1.));
7339 vec2D_dbl_Type w1Loc(1, vec_dbl_Type(weights->size(), -1.));
7340 vec2D_dbl_Type w2Loc(1, vec_dbl_Type(weights->size(), -1.));
7341 vec2D_dbl_Type w3Loc(1, vec_dbl_Type(weights->size(), -1.));
7342 vec2D_dbl_Type pLoc(1, vec_dbl_Type(weights->size(), -1.));
7343 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
7344 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
7345 vec2D_dbl_Type u13(1, vec_dbl_Type(weights->size(), -1.));
7346 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
7347 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
7348 vec2D_dbl_Type u23(1, vec_dbl_Type(weights->size(), -1.));
7349 vec2D_dbl_Type u31(1, vec_dbl_Type(weights->size(), -1.));
7350 vec2D_dbl_Type u32(1, vec_dbl_Type(weights->size(), -1.));
7351 vec2D_dbl_Type u33(1, vec_dbl_Type(weights->size(), -1.));
7352 vec2D_dbl_Type w11(1, vec_dbl_Type(weights->size(), -1.));
7353 vec2D_dbl_Type w12(1, vec_dbl_Type(weights->size(), -1.));
7354 vec2D_dbl_Type w13(1, vec_dbl_Type(weights->size(), -1.));
7355 vec2D_dbl_Type w21(1, vec_dbl_Type(weights->size(), -1.));
7356 vec2D_dbl_Type w22(1, vec_dbl_Type(weights->size(), -1.));
7357 vec2D_dbl_Type w23(1, vec_dbl_Type(weights->size(), -1.));
7358 vec2D_dbl_Type w31(1, vec_dbl_Type(weights->size(), -1.));
7359 vec2D_dbl_Type w32(1, vec_dbl_Type(weights->size(), -1.));
7360 vec2D_dbl_Type w33(1, vec_dbl_Type(weights->size(), -1.));
7361 vec2D_dbl_Type sigma11(1, vec_dbl_Type(weights->size(), -1.));
7362 vec2D_dbl_Type sigma12(1, vec_dbl_Type(weights->size(), -1.));
7363 vec2D_dbl_Type sigma13(1, vec_dbl_Type(weights->size(), -1.));
7364 vec2D_dbl_Type sigma21(1, vec_dbl_Type(weights->size(), -1.));
7365 vec2D_dbl_Type sigma22(1, vec_dbl_Type(weights->size(), -1.));
7366 vec2D_dbl_Type sigma23(1, vec_dbl_Type(weights->size(), -1.));
7367 vec2D_dbl_Type sigma31(1, vec_dbl_Type(weights->size(), -1.));
7368 vec2D_dbl_Type sigma32(1, vec_dbl_Type(weights->size(), -1.));
7369 vec2D_dbl_Type sigma33(1, vec_dbl_Type(weights->size(), -1.));
7371 for (
int T = 0; T < elements->numberElements(); T++)
7373 p1 = pointsRep->at(elements->getElement(T).getNode(0));
7374 p2 = pointsRep->at(elements->getElement(T).getNode(1));
7375 p3 = pointsRep->at(elements->getElement(T).getNode(2));
7376 p4 = pointsRep->at(elements->getElement(T).getNode(3));
7378 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType1);
7379 detB = B.computeInverse(Binv);
7380 absDetB = std::fabs(detB);
7383 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
7384 applyBTinv( dPhiU, dPhiTransU, Binv );
7387 for(
int k = 0; k < phiU->size(); k++)
7395 for(
int i = 0; i < phiU->at(0).size(); i++)
7397 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
7398 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
7399 LO index3 = dim * elements->getElement(T).getNode(i) + 2;
7400 u1Loc[0][k] += uArray[index1] * phiU->at(k).at(i);
7401 u2Loc[0][k] += uArray[index2] * phiU->at(k).at(i);
7402 u3Loc[0][k] += uArray[index3] * phiU->at(k).at(i);
7403 w1Loc[0][k] += wArray[index1] * phiU->at(k).at(i);
7404 w2Loc[0][k] += wArray[index2] * phiU->at(k).at(i);
7405 w3Loc[0][k] += wArray[index3] * phiU->at(k).at(i);
7411 for(
int k = 0; k < phiP->size(); k++)
7414 for(
int i = 0; i < phiP->at(0).size(); i++)
7417 LO index = elements->getElement(T).getNode(i) + 0;
7418 pLoc[0][k] += pArray[index] * phiP->at(k).at(i);
7424 for(
int k = 0; k < dPhiTransU.size(); k++)
7444 for(
int i = 0; i < dPhiTransU[0].size(); i++)
7446 LO index1 = dim * elements->getElement(T).getNode(i) + 0;
7447 LO index2 = dim * elements->getElement(T).getNode(i) + 1;
7448 LO index3 = dim * elements->getElement(T).getNode(i) + 2;
7449 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
7450 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
7451 u13[0][k] += uArray[index1] * dPhiTransU[k][i][2];
7452 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
7453 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
7454 u23[0][k] += uArray[index2] * dPhiTransU[k][i][2];
7455 u31[0][k] += uArray[index3] * dPhiTransU[k][i][0];
7456 u32[0][k] += uArray[index3] * dPhiTransU[k][i][1];
7457 u33[0][k] += uArray[index3] * dPhiTransU[k][i][2];
7458 w11[0][k] += wArray[index1] * dPhiTransU[k][i][0];
7459 w12[0][k] += wArray[index1] * dPhiTransU[k][i][1];
7460 w13[0][k] += wArray[index1] * dPhiTransU[k][i][2];
7461 w21[0][k] += wArray[index2] * dPhiTransU[k][i][0];
7462 w22[0][k] += wArray[index2] * dPhiTransU[k][i][1];
7463 w23[0][k] += wArray[index2] * dPhiTransU[k][i][2];
7464 w31[0][k] += wArray[index3] * dPhiTransU[k][i][0];
7465 w32[0][k] += wArray[index3] * dPhiTransU[k][i][1];
7466 w33[0][k] += wArray[index3] * dPhiTransU[k][i][2];
7472 for(
int k = 0; k < dPhiTransU.size(); k++)
7474 sigma11[0][k] = rho * nu * (u11[0][k] + u11[0][k]) - pLoc[0][k];
7475 sigma12[0][k] = rho * nu * (u12[0][k] + u21[0][k]);
7476 sigma13[0][k] = rho * nu * (u13[0][k] + u31[0][k]);
7477 sigma21[0][k] = rho * nu * (u21[0][k] + u12[0][k]);
7478 sigma22[0][k] = rho * nu * (u22[0][k] + u22[0][k]) - pLoc[0][k];
7479 sigma23[0][k] = rho * nu * (u23[0][k] + u32[0][k]);
7480 sigma31[0][k] = rho * nu * (u31[0][k] + u13[0][k]);
7481 sigma32[0][k] = rho * nu * (u32[0][k] + u23[0][k]);
7482 sigma33[0][k] = rho * nu * (u33[0][k] + u33[0][k]) - pLoc[0][k];
7486 for (
int i = 0; i < dPhiU->at(0).size(); i++)
7488 Teuchos::Array<SC> value11( 1, 0. );
7489 Teuchos::Array<SC> value12( 1, 0. );
7490 Teuchos::Array<SC> value13( 1, 0. );
7491 Teuchos::Array<SC> value21( 1, 0. );
7492 Teuchos::Array<SC> value22( 1, 0. );
7493 Teuchos::Array<SC> value23( 1, 0. );
7494 Teuchos::Array<SC> value31( 1, 0. );
7495 Teuchos::Array<SC> value32( 1, 0. );
7496 Teuchos::Array<SC> value33( 1, 0. );
7497 Teuchos::Array<GO> indices( 1, 0 );
7499 for (
int j = 0; j < dPhiU->at(0).size(); j++)
7567 for (
int k = 0; k < dPhiU->size(); k++)
7570 valDK1_11 = valDK1_11 + weights->at(k) *
7571 ( 2 * u11[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7572 ( u11[0][k] * dPhiTransU[k][j][1] + u21[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
7573 ( u11[0][k] * dPhiTransU[k][j][2] + u31[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
7574 valDK1_12 = valDK1_12 + weights->at(k) *
7575 ( 2 * u12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7576 ( u12[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
7577 ( u12[0][k] * dPhiTransU[k][j][2] + u32[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
7578 valDK1_13 = valDK1_13 + weights->at(k) *
7579 ( 2 * u13[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][0] +
7580 ( u13[0][k] * dPhiTransU[k][j][1] + u23[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][1] +
7581 ( u13[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][0] ) * dPhiTransU[k][i][2] );
7582 valDK1_21 = valDK1_21 + weights->at(k) *
7583 ( ( u21[0][k] * dPhiTransU[k][j][0] + u11[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
7584 2 * u21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
7585 ( u21[0][k] * dPhiTransU[k][j][2] + u31[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7586 valDK1_22 = valDK1_22 + weights->at(k) *
7587 ( ( u22[0][k] * dPhiTransU[k][j][0] + u12[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
7588 2 * u22[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
7589 ( u22[0][k] * dPhiTransU[k][j][2] + u32[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7590 valDK1_23 = valDK1_23 + weights->at(k) *
7591 ( ( u23[0][k] * dPhiTransU[k][j][0] + u13[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][0] +
7592 2 * u23[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][1] +
7593 ( u23[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7594 valDK1_31 = valDK1_31 + weights->at(k) *
7595 ( ( u31[0][k] * dPhiTransU[k][j][0] + u11[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7596 ( u31[0][k] * dPhiTransU[k][j][1] + u21[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
7597 2 * u31[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
7598 valDK1_32 = valDK1_32 + weights->at(k) *
7599 ( ( u32[0][k] * dPhiTransU[k][j][0] + u12[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7600 ( u32[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
7601 2 * u32[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
7602 valDK1_33 = valDK1_33 + weights->at(k) *
7603 ( ( u33[0][k] * dPhiTransU[k][j][0] + u13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7604 ( u33[0][k] * dPhiTransU[k][j][1] + u23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] ) +
7605 2 * u33[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][2];
7608 valDK2_11 = valDK2_11 + weights->at(k) *
7609 ( ( -sigma12[0][k] * dPhiTransU[k][j][1] - sigma13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7610 sigma12[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
7611 sigma13[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
7612 valDK2_12 = valDK2_12 + weights->at(k) *
7613 ( sigma11[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7614 ( -sigma11[0][k] * dPhiTransU[k][j][0] - sigma13[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
7615 sigma13[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
7616 valDK2_13 = valDK2_13 + weights->at(k) *
7617 ( sigma11[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
7618 sigma12[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
7619 ( -sigma11[0][k] * dPhiTransU[k][j][0] - sigma12[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7620 valDK2_21 = valDK2_21 + weights->at(k) *
7621 ( ( -sigma22[0][k] * dPhiTransU[k][j][1] - sigma23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7622 sigma22[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
7623 sigma23[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
7624 valDK2_22 = valDK2_22 + weights->at(k) *
7625 ( sigma21[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7626 ( -sigma21[0][k] * dPhiTransU[k][j][0] - sigma23[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
7627 sigma23[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
7628 valDK2_23 = valDK2_23 + weights->at(k) *
7629 ( sigma21[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
7630 sigma22[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
7631 ( -sigma21[0][k] * dPhiTransU[k][j][0] - sigma22[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7632 valDK2_31 = valDK2_31 + weights->at(k) *
7633 ( ( -sigma32[0][k] * dPhiTransU[k][j][1] - sigma33[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][0] +
7634 sigma32[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][1] +
7635 sigma33[0][k] * dPhiTransU[k][j][0] * dPhiTransU[k][i][2] );
7636 valDK2_32 = valDK2_32 + weights->at(k) *
7637 ( sigma31[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][0] +
7638 ( -sigma31[0][k] * dPhiTransU[k][j][0] - sigma33[0][k] * dPhiTransU[k][j][2] ) * dPhiTransU[k][i][1] +
7639 sigma33[0][k] * dPhiTransU[k][j][1] * dPhiTransU[k][i][2] );
7640 valDK2_33 = valDK2_33 + weights->at(k) *
7641 ( sigma31[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][0] +
7642 sigma32[0][k] * dPhiTransU[k][j][2] * dPhiTransU[k][i][1] +
7643 ( -sigma31[0][k] * dPhiTransU[k][j][0] - sigma32[0][k] * dPhiTransU[k][j][1] ) * dPhiTransU[k][i][2] );
7655 ZN_11 = - ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][1] - ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][2];
7656 ZN_12 = ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][0];
7657 ZN_13 = ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][0];
7658 ZN_21 = ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][1];
7659 ZN_22 = - ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][0] - ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][2];
7660 ZN_23 = ( u3Loc[0][k] - w3Loc[0][k] ) * dPhiTransU[k][j][1];
7661 ZN_31 = ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][2];
7662 ZN_32 = ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][2];
7663 ZN_33 = - ( u1Loc[0][k] - w1Loc[0][k] ) * dPhiTransU[k][j][0] - ( u2Loc[0][k] - w2Loc[0][k] ) * dPhiTransU[k][j][1];
7665 valDN_11 = valDN_11 + weights->at(k) *
7666 ( ZN_11 * u11[0][k] * phiU->at(k).at(i) +
7667 ZN_12 * u12[0][k] * phiU->at(k).at(i) +
7668 ZN_13 * u13[0][k] * phiU->at(k).at(i) );
7669 valDN_12 = valDN_12 + weights->at(k) *
7670 ( ZN_21 * u11[0][k] * phiU->at(k).at(i) +
7671 ZN_22 * u12[0][k] * phiU->at(k).at(i) +
7672 ZN_23 * u13[0][k] * phiU->at(k).at(i) );
7673 valDN_13 = valDN_13 + weights->at(k) *
7674 ( ZN_31 * u11[0][k] * phiU->at(k).at(i) +
7675 ZN_32 * u12[0][k] * phiU->at(k).at(i) +
7676 ZN_33 * u13[0][k] * phiU->at(k).at(i) );
7677 valDN_21 = valDN_21 + weights->at(k) *
7678 ( ZN_11 * u21[0][k] * phiU->at(k).at(i) +
7679 ZN_12 * u22[0][k] * phiU->at(k).at(i) +
7680 ZN_13 * u23[0][k] * phiU->at(k).at(i) );
7681 valDN_22 = valDN_22 + weights->at(k) *
7682 ( ZN_21 * u21[0][k] * phiU->at(k).at(i) +
7683 ZN_22 * u22[0][k] * phiU->at(k).at(i) +
7684 ZN_23 * u23[0][k] * phiU->at(k).at(i) );
7685 valDN_23 = valDN_23 + weights->at(k) *
7686 ( ZN_31 * u21[0][k] * phiU->at(k).at(i) +
7687 ZN_32 * u22[0][k] * phiU->at(k).at(i) +
7688 ZN_33 * u23[0][k] * phiU->at(k).at(i) );
7689 valDN_31 = valDN_31 + weights->at(k) *
7690 ( ZN_11 * u31[0][k] * phiU->at(k).at(i) +
7691 ZN_12 * u32[0][k] * phiU->at(k).at(i) +
7692 ZN_13 * u33[0][k] * phiU->at(k).at(i) );
7693 valDN_32 = valDN_32 + weights->at(k) *
7694 ( ZN_21 * u31[0][k] * phiU->at(k).at(i) +
7695 ZN_22 * u32[0][k] * phiU->at(k).at(i) +
7696 ZN_23 * u33[0][k] * phiU->at(k).at(i) );
7697 valDN_33 = valDN_33 + weights->at(k) *
7698 ( ZN_31 * u31[0][k] * phiU->at(k).at(i) +
7699 ZN_32 * u32[0][k] * phiU->at(k).at(i) +
7700 ZN_33 * u33[0][k] * phiU->at(k).at(i) );
7703 valDW_11 = valDW_11 + weights->at(k) *
7704 ( u11[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7705 valDW_12 = valDW_12 + weights->at(k) *
7706 ( u12[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7707 valDW_13 = valDW_13 + weights->at(k) *
7708 ( u13[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7709 valDW_21 = valDW_21 + weights->at(k) *
7710 ( u21[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7711 valDW_22 = valDW_22 + weights->at(k) *
7712 ( u22[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7713 valDW_23 = valDW_23 + weights->at(k) *
7714 ( u23[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7715 valDW_31 = valDW_31 + weights->at(k) *
7716 ( u31[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7717 valDW_32 = valDW_32 + weights->at(k) *
7718 ( u32[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7719 valDW_33 = valDW_33 + weights->at(k) *
7720 ( u33[0][k] * phiU->at(k).at(j) * phiU->at(k).at(i) );
7726 ZP_1 = -w21[0][k] * dPhiTransU[k][j][1] + w22[0][k] * dPhiTransU[k][j][0] -
7727 w31[0][k] * dPhiTransU[k][j][2] + w33[0][k] * dPhiTransU[k][j][0];
7728 ZP_2 = w11[0][k] * dPhiTransU[k][j][1] - w12[0][k] * dPhiTransU[k][j][0] -
7729 w32[0][k] * dPhiTransU[k][j][2] + w33[0][k] * dPhiTransU[k][j][1];
7730 ZP_3 = w11[0][k] * dPhiTransU[k][j][2] - w13[0][k] * dPhiTransU[k][j][0] +
7731 w22[0][k] * dPhiTransU[k][j][2] - w23[0][k] * dPhiTransU[k][j][1];
7733 valDP_11 = valDP_11 + weights->at(k) *
7734 ( ZP_1 * u1Loc[0][k] * phiU->at(k).at(i) );
7735 valDP_12 = valDP_12 + weights->at(k) *
7736 ( ZP_2 * u1Loc[0][k] * phiU->at(k).at(i) );
7737 valDP_13 = valDP_13 + weights->at(k) *
7738 ( ZP_3 * u1Loc[0][k] * phiU->at(k).at(i) );
7739 valDP_21 = valDP_21 + weights->at(k) *
7740 ( ZP_1 * u2Loc[0][k] * phiU->at(k).at(i) );
7741 valDP_22 = valDP_22 + weights->at(k) *
7742 ( ZP_2 * u2Loc[0][k] * phiU->at(k).at(i) );
7743 valDP_23 = valDP_23 + weights->at(k) *
7744 ( ZP_3 * u2Loc[0][k] * phiU->at(k).at(i) );
7745 valDP_31 = valDP_31 + weights->at(k) *
7746 ( ZP_1 * u3Loc[0][k] * phiU->at(k).at(i) );
7747 valDP_32 = valDP_32 + weights->at(k) *
7748 ( ZP_2 * u3Loc[0][k] * phiU->at(k).at(i) );
7749 valDP_33 = valDP_33 + weights->at(k) *
7750 ( ZP_3 * u3Loc[0][k] * phiU->at(k).at(i) );
7753 valDM_11 = valDM_11 + weights->at(k) *
7754 ( dPhiTransU[k][j][0] * u1Loc[0][k] * phiU->at(k).at(i) );
7755 valDM_12 = valDM_12 + weights->at(k) *
7756 ( dPhiTransU[k][j][1] * u1Loc[0][k] * phiU->at(k).at(i) );
7757 valDM_13 = valDM_13 + weights->at(k) *
7758 ( dPhiTransU[k][j][2] * u1Loc[0][k] * phiU->at(k).at(i) );
7759 valDM_21 = valDM_21 + weights->at(k) *
7760 ( dPhiTransU[k][j][0] * u2Loc[0][k] * phiU->at(k).at(i) );
7761 valDM_22 = valDM_22 + weights->at(k) *
7762 ( dPhiTransU[k][j][1] * u2Loc[0][k] * phiU->at(k).at(i) );
7763 valDM_23 = valDM_23 + weights->at(k) *
7764 ( dPhiTransU[k][j][2] * u2Loc[0][k] * phiU->at(k).at(i) );
7765 valDM_31 = valDM_31 + weights->at(k) *
7766 ( dPhiTransU[k][j][0] * u3Loc[0][k] * phiU->at(k).at(i) );
7767 valDM_32 = valDM_32 + weights->at(k) *
7768 ( dPhiTransU[k][j][1] * u3Loc[0][k] * phiU->at(k).at(i) );
7769 valDM_33 = valDM_33 + weights->at(k) *
7770 ( dPhiTransU[k][j][2] * u3Loc[0][k] * phiU->at(k).at(i) );
7773 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;
7774 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;
7775 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;
7776 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;
7777 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;
7778 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;
7779 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;
7780 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;
7781 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;
7783 val11 = absDetB * val11;
7784 val12 = absDetB * val12;
7785 val13 = absDetB * val13;
7786 val21 = absDetB * val21;
7787 val22 = absDetB * val22;
7788 val23 = absDetB * val23;
7789 val31 = absDetB * val31;
7790 val32 = absDetB * val32;
7791 val33 = absDetB * val33;
7804 glob_j = dim * map->getGlobalElement(elements->getElement(T).getNode(j));
7805 glob_i = dim * map->getGlobalElement(elements->getElement(T).getNode(i));
7806 indices[0] = glob_j;
7808 D->insertGlobalValues(glob_i, indices(), value11());
7809 D->insertGlobalValues(glob_i+1, indices(), value21());
7810 D->insertGlobalValues(glob_i+2, indices(), value31());
7812 indices[0] = glob_j;
7813 D->insertGlobalValues(glob_i, indices(), value12());
7814 D->insertGlobalValues(glob_i+1, indices(), value22());
7815 D->insertGlobalValues(glob_i+2, indices(), value32());
7817 indices[0] = glob_j;
7818 D->insertGlobalValues(glob_i, indices(), value13());
7819 D->insertGlobalValues(glob_i+1, indices(), value23());
7820 D->insertGlobalValues(glob_i+2, indices(), value33());
7824 if (callFillComplete)
7833template <
class SC,
class LO,
class GO,
class NO>
7834void FE<SC,LO,GO,NO>::assemblyShapeDerivativeDivergence(
int dim,
7835 std::string FEType1,
7836 std::string FEType2,
7840 MapConstPtr_Type map1_unique,
7841 MapConstPtr_Type map2_unique,
7842 MultiVectorPtr_Type u,
7843 bool callFillComplete)
7845 DomainConstPtr_Type domain1 = domainVec_.at(FEloc1);
7846 ElementsPtr_Type elements = domain1->getElementsC();
7847 vec2D_dbl_ptr_Type pointsRep = domain1->getPointsRepeated();
7848 MapConstPtr_Type map1_rep = domain1->getMapRepeated();
7851 DomainConstPtr_Type domain2 = domainVec_.at(FEloc2);
7852 MapConstPtr_Type map2_rep = domain2->getMapRepeated();
7853 ElementsPtr_Type elements2 = domain2->getElementsC();
7855 vec3D_dbl_ptr_Type dPhiU;
7856 vec2D_dbl_ptr_Type phiU;
7857 vec2D_dbl_ptr_Type phiP;
7858 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
7859 vec2D_dbl_ptr_Type quadPts;
7861 UN extraDeg = Helper::determineDegree( dim, FEType1, Helper::Deriv1);
7862 UN deg = Helper::determineDegree( dim, FEType1, Helper::Deriv0) + 2*extraDeg;
7865 Helper::getDPhi(dPhiU, weights, dim, FEType1, deg);
7866 Helper::getPhi(phiU, weights, dim, FEType1, deg);
7867 Helper::getPhi(phiP, weights, dim, FEType2, deg);
7868 Helper::getQuadratureValues(dim, deg, quadPts, weights, FEType1);
7873 SmallMatrix<SC> B(dim);
7874 SmallMatrix<SC> Binv(dim);
7878 Teuchos::ArrayRCP< const SC > uArray = u->getData(0);
7883 double valDB_1, valDB_2;
7884 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0);
7889 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
7890 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
7891 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
7892 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
7894 for (
int T = 0; T < elements->numberElements(); T++)
7896 p1 = pointsRep->at(elements->getElement(T).getNode(0));
7897 p2 = pointsRep->at(elements->getElement(T).getNode(1));
7898 p3 = pointsRep->at(elements->getElement(T).getNode(2));
7900 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType1);
7901 detB = B.computeInverse(Binv);
7902 absDetB = std::fabs(detB);
7905 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
7906 applyBTinv( dPhiU, dPhiTransU, Binv );
7910 for(
int k = 0; k < dPhiTransU.size(); k++)
7916 for(
int i = 0; i < dPhiTransU[0].size(); i++)
7918 LO index1 = dim * elements2->getElement(T).getNode(i) + 0;
7919 LO index2 = dim * elements2->getElement(T).getNode(i) + 1;
7920 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
7921 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
7922 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
7923 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
7928 for (
int i = 0; i < phiP->at(0).size(); i++)
7930 Teuchos::Array<SC> value1( 1, 0. );
7931 Teuchos::Array<SC> value2( 1, 0. );
7932 Teuchos::Array<GO> indices( 1, 0 );
7934 for (
int j = 0; j < dPhiU->at(0).size(); j++)
7939 for (
int k = 0; k < dPhiU->size(); k++)
7942 valDB_1 = valDB_1 + weights->at(k) *
7943 ( phiP->at(k).at(i) * ( -u21[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] ) );
7944 valDB_2 = valDB_2 + weights->at(k) *
7945 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][1] - u12[0][k] * dPhiTransU[k][j][0] ) );
7951 val1 = absDetB * val1;
7952 val2 = absDetB * val2;
7957 glob_j = dim * map2_rep->getGlobalElement(elements2->getElement(T).getNode(j));
7958 glob_i = map1_rep->getGlobalElement(elements->getElement(T).getNode(i));
7959 indices[0] = glob_j;
7961 DB->insertGlobalValues(glob_i, indices(), value1());
7963 indices[0] = glob_j;
7964 DB->insertGlobalValues(glob_i, indices(), value2());
7968 if (callFillComplete)
7970 DB->fillComplete(map2_unique, map1_unique);
7975 double val1, val2, val3;
7976 double valDB_1, valDB_2, valDB_3;
7977 vec_dbl_Type p1(3,0.0), p2(3,0.0), p3(3,0.0), p4(3,0.0);
7982 vec2D_dbl_Type u11(1, vec_dbl_Type(weights->size(), -1.));
7983 vec2D_dbl_Type u12(1, vec_dbl_Type(weights->size(), -1.));
7984 vec2D_dbl_Type u13(1, vec_dbl_Type(weights->size(), -1.));
7985 vec2D_dbl_Type u21(1, vec_dbl_Type(weights->size(), -1.));
7986 vec2D_dbl_Type u22(1, vec_dbl_Type(weights->size(), -1.));
7987 vec2D_dbl_Type u23(1, vec_dbl_Type(weights->size(), -1.));
7988 vec2D_dbl_Type u31(1, vec_dbl_Type(weights->size(), -1.));
7989 vec2D_dbl_Type u32(1, vec_dbl_Type(weights->size(), -1.));
7990 vec2D_dbl_Type u33(1, vec_dbl_Type(weights->size(), -1.));
7992 for (
int T = 0; T < elements->numberElements(); T++)
7994 p1 = pointsRep->at(elements->getElement(T).getNode(0));
7995 p2 = pointsRep->at(elements->getElement(T).getNode(1));
7996 p3 = pointsRep->at(elements->getElement(T).getNode(2));
7997 p4 = pointsRep->at(elements->getElement(T).getNode(3));
7999 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B,FEType1);
8000 detB = B.computeInverse(Binv);
8001 absDetB = std::fabs(detB);
8004 vec3D_dbl_Type dPhiTransU( dPhiU->size(), vec2D_dbl_Type( dPhiU->at(0).size(), vec_dbl_Type(dim,0.) ) );
8005 applyBTinv( dPhiU, dPhiTransU, Binv );
8009 for(
int k = 0; k < dPhiTransU.size(); k++)
8021 for(
int i = 0; i < dPhiTransU[0].size(); i++)
8023 LO index1 = dim * elements2->getElement(T).getNode(i) + 0;
8024 LO index2 = dim * elements2->getElement(T).getNode(i) + 1;
8025 LO index3 = dim * elements2->getElement(T).getNode(i) + 2;
8026 u11[0][k] += uArray[index1] * dPhiTransU[k][i][0];
8027 u12[0][k] += uArray[index1] * dPhiTransU[k][i][1];
8028 u13[0][k] += uArray[index1] * dPhiTransU[k][i][2];
8029 u21[0][k] += uArray[index2] * dPhiTransU[k][i][0];
8030 u22[0][k] += uArray[index2] * dPhiTransU[k][i][1];
8031 u23[0][k] += uArray[index2] * dPhiTransU[k][i][2];
8032 u31[0][k] += uArray[index3] * dPhiTransU[k][i][0];
8033 u32[0][k] += uArray[index3] * dPhiTransU[k][i][1];
8034 u33[0][k] += uArray[index3] * dPhiTransU[k][i][2];
8038 for (
int i = 0; i < phiP->at(0).size(); i++)
8040 Teuchos::Array<SC> value1( 1, 0. );
8041 Teuchos::Array<SC> value2( 1, 0. );
8042 Teuchos::Array<SC> value3( 1, 0. );
8043 Teuchos::Array<GO> indices( 1, 0 );
8045 for (
int j = 0; j < dPhiU->at(0).size(); j++)
8051 for (
int k = 0; k < dPhiU->size(); k++)
8054 valDB_1 = valDB_1 + weights->at(k) *
8055 ( phiP->at(k).at(i) * ( -u21[0][k] * dPhiTransU[k][j][1] + u22[0][k] * dPhiTransU[k][j][0] -
8056 u31[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][0] ) );
8057 valDB_2 = valDB_2 + weights->at(k) *
8058 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][1] - u12[0][k] * dPhiTransU[k][j][0] -
8059 u32[0][k] * dPhiTransU[k][j][2] + u33[0][k] * dPhiTransU[k][j][1] ) );
8060 valDB_3 = valDB_3 + weights->at(k) *
8061 ( phiP->at(k).at(i) * ( u11[0][k] * dPhiTransU[k][j][2] - u13[0][k] * dPhiTransU[k][j][0] +
8062 u22[0][k] * dPhiTransU[k][j][2] - u23[0][k] * dPhiTransU[k][j][1] ) );
8069 val1 = absDetB * val1;
8070 val2 = absDetB * val2;
8071 val3 = absDetB * val3;
8077 glob_j = dim * map2_rep->getGlobalElement(elements2->getElement(T).getNode(j));
8078 glob_i = map1_rep->getGlobalElement(elements->getElement(T).getNode(i));
8079 indices[0] = glob_j;
8081 DB->insertGlobalValues(glob_i, indices(), value1());
8083 indices[0] = glob_j;
8084 DB->insertGlobalValues(glob_i, indices(), value2());
8086 indices[0] = glob_j;
8087 DB->insertGlobalValues(glob_i, indices(), value3());
8091 if (callFillComplete)
8093 DB->fillComplete(map2_unique, map1_unique);
8099template <
class SC,
class LO,
class GO,
class NO>
8100void FE<SC,LO,GO,NO>::assemblySurfaceIntegralExternal(
int dim,
8102 MultiVectorPtr_Type f,
8103 MultiVectorPtr_Type d_rep,
8104 std::vector<SC>& funcParameter,
8106 ParameterListPtr_Type params,
8109 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8111 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8114 SmallMatrix<SC> B(dim);
8115 vec_dbl_Type b(dim);
8117 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
8119 int flagSurface = params->sublist(
"Parameter Solid").get(
"Flag Surface",5);
8121 std::vector<double> valueFunc(dim);
8123 SC* paramsFunc = &(funcParameter[0]);
8126 for (UN T=0; T<elements->numberElements(); T++) {
8127 FiniteElement fe = elements->getElement( T );
8128 ElementsPtr_Type subEl = fe.getSubElements();
8129 for (
int surface=0; surface<fe.numSubElements(); surface++) {
8130 FiniteElement feSub = subEl->getElement( surface );
8131 if(subEl->getDimension() == dim-1 ){
8133 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
8136 vec_dbl_Type solution_d = getSolution(nodeList, d_rep,dim);
8137 vec2D_dbl_Type nodes;
8138 nodes = getCoordinates(nodeList, pointsRep);
8141 double positions[18];
8143 for(
int i=0;i<6;i++)
8144 for(
int j=0;j<3;j++){
8145 positions[count] = nodes[i][j];
8151 paramsFunc[ funcParameter.size() - 1 ] = feSub.getFlag();
8152 vec_dbl_Type p1 = {0.,0.,0.};
8153 func( &p1[0], &valueFunc[0], paramsFunc);
8155 if(valueFunc[0] != 0.){
8157 double *residuumVector;
8158 #ifdef FEDD_HAVE_ACEGENINTERFACE
8160 AceGenInterface::PressureTriangle3D6 pt(valueFunc[0], 1., 35, &positions[0], &solution_d[0]);
8161 pt.computeTangentResidual();
8162 residuumVector = pt.getResiduum();
8165 for(
int i=0; i< nodeList.size() ; i++){
8166 for(
int d=0; d<dim; d++)
8167 valuesF[nodeList[i]*dim+d] += residuumVector[i*dim+d];
8183template <
class SC,
class LO,
class GO,
class NO>
8186 MultiVectorPtr_Type f,
8187 MultiVectorPtr_Type d_rep,
8188 MatrixPtr_Type &Kext,
8189 std::vector<SC>& funcParameter,
8191 ParameterListPtr_Type params,
8196 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8198 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8200 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
8203 vec_dbl_Type b(dim);
8205 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
8207 std::vector<double> valueFunc(dim);
8209 SC* paramsFunc = &(funcParameter[0]);
8212 for (UN T=0; T<elements->numberElements(); T++) {
8214 ElementsPtr_Type subEl = fe.getSubElements();
8215 for (
int surface=0; surface<fe.numSubElements(); surface++) {
8217 if(subEl->getDimension() == dim-1 ){
8218 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
8220 vec_dbl_Type solution_d = getSolution(nodeList, d_rep,dim);
8221 vec2D_dbl_Type nodes;
8222 nodes = getCoordinates(nodeList, pointsRep);
8225 double positions[18];
8227 for(
int i=0;i<6;i++){
8228 for(
int j=0;j<3;j++){
8229 positions[count] = nodes[i][j];
8235 vec_dbl_Type p1 = {0.,0.,0.};
8236 paramsFunc[ funcParameter.size() - 1 ] = feSub.getFlag();
8237 func( &p1[0], &valueFunc[0], paramsFunc);
8239 if(valueFunc[0] != 0.){
8241 double *residuumVector;
8244 #ifdef FEDD_HAVE_ACEGENINTERFACE
8245 AceGenInterface::PressureTriangle3D6 pt(valueFunc[0], 1.0, 35, &positions[0], &solution_d[0]);
8246 pt.computeTangentResidual();
8248 residuumVector = pt.getResiduum();
8249 stiffMat = pt.getStiffnessMatrix();
8255 int numNodes1 =nodeList.size();
8257 SmallMatrix_Type elementMatrixPrint(18,0.);
8258 for(
int i=0; i< 18 ; i++){
8259 for(
int j=0; j< 18; j++){
8260 if(std::fabs(stiffMat[i][j]) >1e-13)
8261 elementMatrixPrint[i][j] = stiffMat[i][j];
8266 SmallMatrix_Type elementMatrixWrite(18,0.);
8268 SmallMatrix_Type elementMatrixIDsRow(18,0.);
8269 SmallMatrix_Type elementMatrixIDsCol(18,0.);
8272 for (UN i=0; i < numNodes1 ; i++) {
8273 for(
int di=0; di<dim; di++){
8274 Teuchos::Array<SC> value1( numNodes1*dim, 0. );
8275 Teuchos::Array<GO> columnIndices1( numNodes1*dim, 0 );
8276 GO row =GO (dim* map->getGlobalElement( nodeList[i] )+di);
8277 LO rowLO = dim*i+di;
8279 for (UN j=0; j <numNodes1; j++){
8280 for(
int d=0; d<dim; d++){
8281 columnIndices1[dim*j+d] = GO ( dim * map->getGlobalElement( nodeList[j] ) + d );
8282 value1[dim*j+d] = stiffMat[rowLO][dim*j+d];
8285 Kext->insertGlobalValues( row, columnIndices1(), value1() );
8291 for(
int i=0; i< nodeList.size() ; i++){
8292 for(
int d=0; d<dim; d++){
8293 valuesF[nodeList[i]*dim+d] += residuumVector[i*dim+d];
8305 Kext->fillComplete(domainVec_.at(FEloc)->getMapVecFieldUnique(),domainVec_.at(FEloc)->getMapVecFieldUnique());
8309template <
class SC,
class LO,
class GO,
class NO>
8310void FE<SC,LO,GO,NO>::computeSurfaceNormal(
int dim,
8311 vec2D_dbl_ptr_Type pointsRep,
8312 vec_int_Type nodeList,
8317 vec_dbl_Type p1(dim),p2(dim);
8320 v_E[0] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
8321 v_E[1] = -(pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0));
8322 norm_v_E = std::sqrt(std::pow(v_E[0],2)+std::pow(v_E[1],2));
8327 p1[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[1]).at(0);
8328 p1[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[1]).at(1);
8329 p1[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[1]).at(2);
8331 p2[0] = pointsRep->at(nodeList[0]).at(0) - pointsRep->at(nodeList[2]).at(0);
8332 p2[1] = pointsRep->at(nodeList[0]).at(1) - pointsRep->at(nodeList[2]).at(1);
8333 p2[2] = pointsRep->at(nodeList[0]).at(2) - pointsRep->at(nodeList[2]).at(2);
8335 v_E[0] = p1[1]*p2[2] - p1[2]*p2[1];
8336 v_E[1] = p1[2]*p2[0] - p1[0]*p2[2];
8337 v_E[2] = p1[0]*p2[1] - p1[1]*p2[0];
8339 norm_v_E = std::sqrt(std::pow(v_E[0],2)+std::pow(v_E[1],2)+std::pow(v_E[2],2));
8345template <
class SC,
class LO,
class GO,
class NO>
8346void FE<SC,LO,GO,NO>::assemblySurfaceIntegral(
int dim,
8348 MultiVectorPtr_Type f,
8349 std::string fieldType,
8351 std::vector<SC>& funcParameter) {
8355 UN FEloc = checkFE(dim,FEType);
8357 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8359 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8361 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
8362 vec2D_dbl_ptr_Type phi;
8363 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
8365 UN degFunc = funcParameter[funcParameter.size()-1] + 1.e-14;
8366 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0) + degFunc;
8368 Helper::getPhi(phi, weights, dim-1, FEType, deg);
8370 vec2D_dbl_ptr_Type quadPoints;
8371 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
8372 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
8376 SmallMatrix<SC> B(dim);
8377 vec_dbl_Type b(dim);
8379 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
8383 std::vector<double> valueFunc(dim);
8385 SC* params = &(funcParameter[0]);
8386 for (UN T=0; T<elements->numberElements(); T++) {
8387 FiniteElement fe = elements->getElement( T );
8388 ElementsPtr_Type subEl = fe.getSubElements();
8389 for (
int surface=0; surface<fe.numSubElements(); surface++) {
8390 FiniteElement feSub = subEl->getElement( surface );
8391 if(subEl->getDimension() == dim-1){
8393 params[ funcParameter.size() - 1 ] = feSub.getFlag();
8395 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
8397 vec_dbl_Type v_E(dim,1.);
8400 Helper::computeSurfaceNormal(dim, pointsRep,nodeList,v_E,norm_v_E);
8402 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
8403 elScaling = B.computeScaling( );
8405 for (UN i=0; i < phi->at(0).size(); i++) {
8406 Teuchos::Array<SC> value(0);
8407 if ( fieldType ==
"Scalar" )
8408 value.resize( 1, 0. );
8409 else if ( fieldType ==
"Vector" )
8410 value.resize( dim, 0. );
8412 for (UN w=0; w<phi->size(); w++) {
8413 vec_dbl_Type x(dim,0.);
8414 for (
int k=0; k<dim; k++) {
8415 for (
int l=0; l<dim-1; l++){
8416 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ];
8421 func( &x[0], &valueFunc[0], params);
8422 if ( fieldType ==
"Scalar" )
8423 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
8424 else if ( fieldType ==
"Vector" ){
8425 for (
int j=0; j<value.size(); j++){
8426 value[j] += weights->at(w) * valueFunc[j]*v_E[j]/norm_v_E * (*phi)[w][i];
8431 for (
int j=0; j<value.size(); j++)
8432 value[j] *= elScaling;
8434 if ( fieldType==
"Scalar" )
8435 valuesF[ nodeList[ i ] ] += value[0];
8438 else if ( fieldType==
"Vector" ){
8439 for (
int j=0; j<value.size(); j++)
8440 valuesF[ dim * nodeList[ i ] + j ] += value[j];
8449template <
class SC,
class LO,
class GO,
class NO>
8450void FE<SC,LO,GO,NO>::assemblySurfaceIntegralFlag(
int dim,
8452 MultiVectorPtr_Type f,
8453 std::string fieldType,
8455 std::vector<SC>& funcParameter) {
8458 TEUCHOS_TEST_FOR_EXCEPTION(funcParameter[0]!=0,std::logic_error,
"We only support constant functions for now.");
8460 UN FEloc = checkFE(dim,FEType);
8462 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8464 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8466 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
8467 vec2D_dbl_ptr_Type phi;
8468 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
8469 UN degFunc = funcParameter[0] + 1.e-14;
8470 UN deg = Helper::determineDegree( dim-1, FEType, Helper::Deriv0) + degFunc;
8472 Helper::getPhi(phi, weights, dim-1, FEType, deg);
8474 vec2D_dbl_ptr_Type quadPoints;
8475 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
8476 Helper::getQuadratureValues(dim-1, deg, quadPoints, w, FEType);
8480 SmallMatrix<SC> B(dim);
8481 vec_dbl_Type b(dim);
8483 Teuchos::ArrayRCP< SC > valuesF = f->getDataNonConst(0);
8486 std::vector<double> valueFunc(dim);
8487 SC* params = &(funcParameter[1]);
8488 for (UN T=0; T<elements->numberElements(); T++) {
8489 FiniteElement fe = elements->getElement( T );
8490 ElementsPtr_Type subEl = fe.getSubElements();
8491 for (
int surface=0; surface<fe.numSubElements(); surface++) {
8492 FiniteElement feSub = subEl->getElement( surface );
8493 if (params[1] == feSub.getFlag()){
8494 FiniteElement feSub = subEl->getElement( surface );
8495 vec_int_Type nodeList = feSub.getVectorNodeListNonConst ();
8496 Helper::buildTransformationSurface( nodeList, pointsRep, B, b, FEType);
8497 elScaling = B.computeScaling( );
8499 for (UN i=0; i < phi->at(0).size(); i++) {
8500 Teuchos::Array<SC> value(0);
8501 if ( fieldType ==
"Scalar" )
8502 value.resize( 1, 0. );
8503 else if ( fieldType ==
"Vector" )
8504 value.resize( dim, 0. );
8506 for (UN w=0; w<phi->size(); w++) {
8507 vec_dbl_Type x(dim,0.);
8508 for (
int k=0; k<dim; k++) {
8509 for (
int l=0; l<dim-1; l++)
8510 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ];
8514 func( &x[0], &valueFunc[0], params[0], params);
8516 if ( fieldType ==
"Scalar" )
8517 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
8518 else if ( fieldType ==
"Vector" ){
8519 for (
int j=0; j<value.size(); j++){
8520 value[j] += weights->at(w) * valueFunc[j] * (*phi)[w][i];
8525 for (
int j=0; j<value.size(); j++)
8526 value[j] *= elScaling;
8528 if ( fieldType==
"Scalar" )
8529 valuesF[ nodeList[ i ] ] += value[0];
8532 else if ( fieldType==
"Vector" ){
8533 for (
int j=0; j<value.size(); j++)
8534 valuesF[ dim * nodeList[ i ] + j ] += value[j];
8543template <
class SC,
class LO,
class GO,
class NO>
8544void FE<SC,LO,GO,NO>::assemblyRHS(
int dim,
8546 MultiVectorPtr_Type a,
8547 std::string fieldType,
8549 std::vector<SC>& funcParameter
8552 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
8554 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error,
"MultiVector in assemblyConstRHS is null." );
8555 TEUCHOS_TEST_FOR_EXCEPTION( a->getNumVectors()>1, std::logic_error,
"Implement for numberMV > 1 ." );
8557 FEloc = checkFE(dim,FEType);
8559 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8561 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8563 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
8564 vec2D_dbl_ptr_Type phi;
8565 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
8572 UN deg = Helper::determineDegree( dim, FEType, Helper::Deriv0) + degFunc;
8574 vec2D_dbl_ptr_Type quadPoints;
8575 Helper::getQuadratureValues(dim, deg, quadPoints, weights, FEType);
8578 Helper::getPhi(phi, weights, dim, FEType, deg);
8582 SmallMatrix<SC> B(dim);
8584 vec_dbl_Type v_i(dim);
8585 vec_dbl_Type v_j(dim);
8587 Teuchos::ArrayRCP< SC > valuesRhs = a->getDataNonConst(0);
8591 std::vector<double> valueFunc(dim);
8592 SC* paras = &(funcParameter[0]);
8594 func( &x, &valueFunc[0], paras );
8597 for (UN T=0; T<elements->numberElements(); T++) {
8599 Helper::buildTransformation(elements->getElement(T).getVectorNodeList(), pointsRep, B, FEType);
8600 detB = B.computeDet( );
8601 absDetB = std::fabs(detB);
8603 vec2D_dbl_Type quadPointsTrans(weights->size(),vec_dbl_Type(dim));
8604 for(
int i=0; i< weights->size(); i++){
8605 for(
int j=0; j< dim ; j++){
8606 for(
int k=0; k< dim; k++){
8607 quadPointsTrans[i][j] += B[j][k]* quadPoints->at(i).at(k) ;
8609 quadPointsTrans[i][j] += pointsRep->at(elements->getElement(T).getNode(0)).at(j);
8612 for (UN i=0; i < phi->at(0).size(); i++) {
8613 if ( !fieldType.compare(
"Scalar") ) {
8614 value = Teuchos::ScalarTraits<SC>::zero();
8615 for (UN w=0; w<weights->size(); w++){
8616 func(&quadPointsTrans[w][0], &valueFunc[0] ,paras);
8617 value += weights->at(w) * phi->at(w).at(i)*valueFunc[0];
8620 LO row = (LO) elements->getElement(T).getNode(i);
8621 valuesRhs[row] += value;
8623 else if( !fieldType.compare(
"Vector") ) {
8624 for (UN d=0; d<dim; d++) {
8625 value = Teuchos::ScalarTraits<SC>::zero();
8626 for (UN w=0; w<weights->size(); w++){
8627 func(&quadPointsTrans[w][0], &valueFunc[0] ,paras);
8628 value += weights->at(w) * phi->at(w).at(i)*valueFunc[d];
8632 LO row = (LO) ( dim * elements->getElement(T).getNode(i) + d );
8633 valuesRhs[row] += v_i;
8637 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Invalid field type." );
8648template <
class SC,
class LO,
class GO,
class NO>
8651 MultiVectorPtr_Type a)
8654 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
8656 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error,
"Multivector is null." );
8659 FEloc = checkFE(dim,FEType);
8661 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8663 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8665 vec2D_dbl_ptr_Type phi;
8666 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
8670 vec2D_dbl_ptr_Type quadPoints;
8680 MultiVectorPtr_Type a_rep = Teuchos::rcp(
new MultiVector_Type( domainVec_.at(FEloc)->getMapRepeated(), 1 ) );
8681 a_rep->putScalar(0.);
8682 Teuchos::ArrayRCP< SC > values_a = a_rep->getDataNonConst(0);
8684 for (UN T=0; T<elements->numberElements(); T++) {
8687 detB = B.computeDet( );
8688 absDetB = std::fabs(detB);
8690 for (UN i=0; i < phi->at(0).size(); i++) {
8691 Teuchos::Array<SC> value( 1, 0. );
8692 for (UN w=0; w<weights->size(); w++){
8693 value[0] += weights->at(w) * phi->at(w).at(i)*1.0;
8695 value[0] *= absDetB;
8696 LO row = (LO) elements->getElement(T).getNode(i);
8698 values_a[row] += value[0];
8704 a->exportFromVector( a_rep,
true,
"Add" );
8708template <
class SC,
class LO,
class GO,
class NO>
8709void FE<SC,LO,GO,NO>::assemblyRHSDegTest(
int dim,
8711 MultiVectorPtr_Type a,
8712 std::string fieldType,
8714 std::vector<SC>& funcParameter,
8717 TEUCHOS_TEST_FOR_EXCEPTION(FEType ==
"P0",std::logic_error,
"Not implemented for P0");
8719 TEUCHOS_TEST_FOR_EXCEPTION( a.is_null(), std::runtime_error,
"MultiVector in assemblyConstRHS is null." );
8720 TEUCHOS_TEST_FOR_EXCEPTION( a->getNumVectors()>1, std::logic_error,
"Implement for numberMV > 1 ." );
8722 UN FEloc = checkFE(dim,FEType);
8724 ElementsPtr_Type elements = domainVec_.at(FEloc)->getElementsC();
8726 vec2D_dbl_ptr_Type pointsRep = domainVec_.at(FEloc)->getPointsRepeated();
8728 MapConstPtr_Type map = domainVec_.at(FEloc)->getMapRepeated();
8729 vec2D_dbl_ptr_Type phi;
8730 vec_dbl_ptr_Type weights = Teuchos::rcp(
new vec_dbl_Type(0));
8733 vec2D_dbl_ptr_Type quadPoints;
8734 vec_dbl_ptr_Type w = Teuchos::rcp(
new vec_dbl_Type(0));
8742 vec_dbl_Type b(dim);
8744 vec_dbl_Type v_i(dim);
8745 vec_dbl_Type v_j(dim);
8747 Teuchos::ArrayRCP< SC > valuesRhs = a->getDataNonConst(0);
8751 std::vector<double> valueFunc(dim);
8752 SC* params = &(funcParameter[1]);
8753 for (UN T=0; T<elements->numberElements(); T++) {
8756 detB = B.computeDet( );
8757 absDetB = std::fabs(detB);
8759 for (UN i=0; i < phi->at(0).size(); i++) {
8760 Teuchos::Array<SC> value(1);
8761 for (UN w=0; w<weights->size(); w++){
8762 vec_dbl_Type x(dim,0.);
8763 for (
int k=0; k<dim; k++) {
8764 for (
int l=0; l<dim; l++)
8765 x[ k ] += B[k][l] * (*quadPoints)[ w ][ l ] + b[k];
8768 func( &x[0], &valueFunc[0], params);
8769 if ( !fieldType.compare(
"Scalar") ) {
8770 value[0] += weights->at(w) * valueFunc[0] * (*phi)[w][i];
8772 else if( !fieldType.compare(
"Vector") ) {
8773 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"No test for field type Vector." );
8776 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Invalid field type." );
8779 value[0] *= absDetB;
8780 LO row = (LO) elements->getElement(T).getNode(i);
8781 valuesRhs[row] += value[0];
8788template <
class SC,
class LO,
class GO,
class NO>
8789void FE<SC,LO,GO,NO>::buildFullDPhi(vec3D_dbl_ptr_Type dPhi, Teuchos::Array<SmallMatrix<double> >& dPhiMat){
8791 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.");
8793 int dim = dPhi->at(0).at(0).size();
8794 int nmbBasisFunc = dPhi->at(0).size();
8795 int nmbTotalBasisFunc = nmbBasisFunc * dim;
8797 for (
int p=0; p<dPhi->size(); p++) {
8798 for (
int i=0; i<nmbBasisFunc; i++) {
8799 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][0] = dPhi->at(p).at(i).at(0);
8800 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][1] = dPhi->at(p).at(i).at(1);
8801 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][0] = 0.;
8802 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][1] = 0.;
8804 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][0] = 0.;
8805 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][1] = 0.;
8806 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][0] = dPhi->at(p).at(i).at(0);
8807 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][1] = dPhi->at(p).at(i).at(1);
8812 for (
int p=0; p<dPhi->size(); p++) {
8813 for (
int i=0; i<nmbBasisFunc; i++) {
8814 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][0] = dPhi->at(p).at(i).at(0);
8815 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][1] = dPhi->at(p).at(i).at(1);
8816 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][0][2] = dPhi->at(p).at(i).at(2);
8817 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][0] = 0.;
8818 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][1] = 0.;
8819 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][1][2] = 0.;
8820 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][0] = 0.;
8821 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][1] = 0.;
8822 dPhiMat[ p * nmbTotalBasisFunc + dim*i ][2][2] = 0.;
8824 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][0] = 0.;
8825 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][1] = 0.;
8826 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][0][2] = 0.;
8827 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][0] = dPhi->at(p).at(i).at(0);
8828 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][1] = dPhi->at(p).at(i).at(1);
8829 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][1][2] = dPhi->at(p).at(i).at(2);
8830 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][0] = 0.;
8831 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][1] = 0.;
8832 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 1 ][2][2] = 0.;
8834 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][0] = 0.;
8835 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][1] = 0.;
8836 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][0][2] = 0.;
8837 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][0] = 0.;
8838 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][1] = 0.;
8839 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][1][2] = 0.;
8840 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][0] = dPhi->at(p).at(i).at(0);
8841 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][1] = dPhi->at(p).at(i).at(1);
8842 dPhiMat[ p * nmbTotalBasisFunc + dim*i + 2 ][2][2] = dPhi->at(p).at(i).at(2);
8848template <
class SC,
class LO,
class GO,
class NO>
8849void FE<SC,LO,GO,NO>::fillMatrixArray(SmallMatrix<double> &matIn,
double* matArrayOut, std::string order,
int offset){
8850 if (!order.compare(
"cols")) {
8851 for (
int j=0; j<matIn.size(); j++) {
8852 for (
int i=0; i<matIn.size(); i++) {
8853 matArrayOut[ j * matIn.size() + i + offset ] = matIn[i][j];
8857 else if(!order.compare(
"rows")) {
8858 for (
int i=0; i<matIn.size(); i++) {
8859 for (
int j=0; j<matIn.size(); j++) {
8860 matArrayOut[ i * matIn.size() + j + offset ] = matIn[i][j];
8865 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
"Unknown ordering for matrix to array conversion. Choose rows or cols.");
8868template <
class SC,
class LO,
class GO,
class NO>
8869void FE<SC,LO,GO,NO>::epsilonTensor(vec_dbl_Type &basisValues, SmallMatrix<SC> &epsilonValues,
int activeDof){
8871 for (
int i=0; i<epsilonValues.size(); i++) {
8872 for (
int j=0; j<epsilonValues.size(); j++) {
8873 epsilonValues[i][j] = 0.;
8875 epsilonValues[i][j] += 0.5*basisValues.at(j);
8878 epsilonValues[i][j] += 0.5*basisValues.at(i);
8884template <
class SC,
class LO,
class GO,
class NO>
8885int FE<SC,LO,GO,NO>::checkFE(
int dim,
8886 std::string FEType){
8889 std::vector<int> matches;
8890 for (
int i = 0; i < domainVec_.size(); i++) {
8891 if (domainVec_.at(i)->getDimension() == dim)
8892 matches.push_back(i);
8896 for (
int i = 0; i < matches.size();i++) {
8897 if (domainVec_.at( matches.at(i) )->getFEType() == FEType) {
8898 FEloc = matches.at(i);
8903 TEUCHOS_TEST_FOR_EXCEPTION(!found, std::logic_error ,
"Combination of dimenson(2/3) and FE Type(P1/P2) not defined yet. Use addFE(domain)");
8921template <
class SC,
class LO,
class GO,
class NO>
8922void FE<SC,LO,GO,NO>::nh3d(
double* v,
double (*E),
double (*Nu),
double** F ,
double** Pmat,
double**** Amat)
8926 v[323]=(*E)/(1e0+(*Nu));
8927 v[3]=((*Nu)*v[323])/(1e0-2e0*(*Nu));
8937 v[18]=F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1];
8938 v[335]=(v[18]*v[18]);
8940 v[24]=F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2];
8941 v[334]=(v[24]*v[24]);
8943 v[22]=F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2];
8944 v[15]=Power(F[0][0],2)+Power(F[1][0],2)+Power(F[2][0],2);
8945 v[228]=-(F[2][1]*v[18]);
8946 v[225]=F[2][2]*v[18];
8947 v[217]=-(F[1][1]*v[18]);
8948 v[214]=F[1][2]*v[18];
8949 v[194]=-(F[2][0]*v[18]);
8950 v[185]=-(F[1][0]*v[18]);
8951 v[268]=F[2][1]*v[22];
8952 v[264]=-(F[2][2]*v[22]);
8953 v[255]=F[1][1]*v[22];
8954 v[251]=-(F[1][2]*v[22]);
8955 v[190]=-(F[2][0]*v[22]);
8956 v[181]=-(F[1][0]*v[22]);
8957 v[172]=-(F[0][0]*v[22]);
8958 v[20]=Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2);
8959 v[324]=-(v[20]*v[22]);
8960 v[327]=2e0*(v[324]+v[325]);
8964 v[138]=v[15]*v[20]-v[335];
8965 v[270]=F[2][0]*v[24];
8966 v[260]=-(F[2][2]*v[24]);
8967 v[257]=F[1][0]*v[24];
8968 v[247]=-(F[1][2]*v[24]);
8969 v[244]=F[0][0]*v[24];
8970 v[232]=-(F[0][2]*v[24]);
8971 v[222]=-(F[2][1]*v[24]);
8972 v[211]=-(F[1][1]*v[24]);
8973 v[198]=-(F[0][1]*v[24]);
8974 v[168]=v[18]*v[22]-v[15]*v[24];
8978 v[38]=-(v[22]*v[22]);
8979 v[26]=Power(F[0][2],2)+Power(F[1][2],2)+Power(F[2][2],2);
8980 v[333]=v[20]*v[26]-v[334];
8981 v[351]=2e0*F[0][0]*v[333];
8982 v[236]=v[22]*v[24]-v[18]*v[26];
8991 v[148]=v[15]*v[26]+v[38];
8992 v[29]=v[148]*v[20]+2e0*v[22]*v[325]-v[15]*v[334]-v[26]*v[335];
8993 v[336]=1e0/Power(v[29],2);
8994 v[32]=-v[5]+v[3]*std::log(std::sqrt(v[29]));
8995 v[337]=(v[3]/4e0-v[32]/2e0)*v[336];
8996 v[137]=v[337]*(F[2][1]*v[326]+F[2][0]*v[327]-v[335]*v[88]+v[15]*v[94]);
8997 v[147]=v[137]*v[138];
8998 v[136]=v[337]*(F[2][2]*v[329]+F[2][0]*v[330]+v[38]*v[67]+v[15]*v[93]);
8999 v[156]=v[136]*v[148];
9000 v[135]=v[337]*(F[2][2]*v[327]+F[2][1]*v[328]-v[334]*v[58]+v[20]*v[99]);
9001 v[165]=v[135]*v[333];
9002 v[134]=v[337]*(F[1][1]*v[326]+F[1][0]*v[327]-v[335]*v[87]+v[15]*v[92]);
9003 v[144]=v[134]*v[138];
9004 v[133]=v[337]*(F[1][2]*v[331]+F[1][0]*v[332]+v[38]*v[66]+v[15]*v[91]);
9005 v[153]=v[133]*v[148];
9006 v[132]=v[337]*(F[1][2]*v[327]+F[1][1]*v[328]-v[334]*v[57]+v[20]*v[97]);
9007 v[162]=v[132]*v[333];
9008 v[131]=v[337]*(F[0][0]*v[327]+F[0][1]*v[329]-v[335]*v[86]+v[15]*v[90]);
9009 v[130]=v[337]*(F[0][2]*v[331]+F[0][0]*v[332]+v[38]*v[65]+v[15]*v[89]);
9010 v[128]=v[337]*(F[0][2]*v[327]+F[0][1]*v[330]+v[351]);
9011 v[37]=v[32]/(2e0*v[29]);
9012 v[355]=v[37]*(2e0*v[172]+v[15]*v[86]);
9013 v[353]=v[37]*(2e0*v[232]+v[89]);
9014 v[352]=v[37]*(2e0*v[198]+v[90]);
9015 v[349]=-2e0*(F[1][0]*v[20]+v[217])*v[37];
9016 v[348]=-(v[37]*(2e0*v[185]+v[15]*v[66]));
9017 v[347]=-2e0*(F[2][0]*v[20]+v[228])*v[37];
9018 v[346]=-(v[37]*(2e0*v[194]+v[15]*v[67]));
9019 v[345]=-(v[37]*(2e0*v[251]+v[97]));
9020 v[344]=-(v[37]*(2e0*v[181]+v[15]*v[87]));
9021 v[343]=-(v[37]*(2e0*v[264]+v[99]));
9022 v[342]=-(v[37]*(2e0*v[190]+v[15]*v[88]));
9023 v[341]=-(v[37]*(2e0*v[247]+v[91]));
9024 v[340]=-(v[37]*(2e0*v[211]+v[92]));
9025 v[339]=-(v[37]*(2e0*v[260]+v[93]));
9026 v[338]=-(v[37]*(2e0*v[222]+v[94]));
9027 v[272]=v[137]*v[328]+v[37]*(2e0*v[268]+2e0*v[270]-2e0*v[18]*v[88]);
9028 v[267]=v[136]*v[328]+v[343];
9029 v[263]=v[135]*v[328]+v[339];
9030 v[259]=v[134]*v[328]+v[37]*(2e0*v[255]+2e0*v[257]-2e0*v[18]*v[87]);
9031 v[254]=v[133]*v[328]+v[345];
9032 v[250]=v[132]*v[328]+v[341];
9033 v[246]=v[131]*v[328]+v[37]*(2e0*F[0][1]*v[22]+2e0*v[244]-2e0*v[18]*v[86]);
9034 v[241]=v[130]*v[328]+2e0*(F[0][2]*v[22]-F[0][0]*v[26])*v[37];
9035 v[231]=v[137]*v[327]+v[347];
9036 v[227]=v[136]*v[327]+v[37]*(2e0*v[225]+2e0*v[270]-2e0*v[22]*v[67]);
9037 v[224]=v[135]*v[327]+v[338];
9038 v[301]=2e0*F[1][0]*v[165]+F[1][2]*v[224]+F[1][1]*v[263];
9039 v[279]=2e0*F[0][0]*v[165]+F[0][2]*v[224]+F[0][1]*v[263];
9040 v[220]=v[134]*v[327]+v[349];
9041 v[216]=v[133]*v[327]+v[37]*(2e0*v[214]+2e0*v[257]-2e0*v[22]*v[66]);
9042 v[213]=v[132]*v[327]+v[340];
9043 v[276]=2e0*F[0][0]*v[162]+F[0][2]*v[213]+F[0][1]*v[250];
9044 v[209]=v[131]*v[327]+2e0*(F[0][1]*v[18]-F[0][0]*v[20])*v[37];
9045 v[196]=v[137]*v[326]+v[346];
9046 v[314]=2e0*F[1][2]*v[147]+F[1][1]*v[196]+F[1][0]*v[231];
9047 v[296]=2e0*F[0][2]*v[147]+F[0][1]*v[196]+F[0][0]*v[231];
9048 v[192]=v[136]*v[326]+v[342];
9049 v[308]=2e0*F[1][1]*v[156]+F[1][2]*v[192]+F[1][0]*v[267];
9050 v[288]=2e0*F[0][1]*v[156]+F[0][2]*v[192]+F[0][0]*v[267];
9051 v[188]=v[135]*v[326]+v[37]*(2e0*v[225]+2e0*v[268]-2e0*v[24]*v[58]);
9052 v[187]=v[134]*v[326]+v[348];
9053 v[293]=2e0*F[0][2]*v[144]+F[0][1]*v[187]+F[0][0]*v[220];
9054 v[183]=v[133]*v[326]+v[344];
9055 v[285]=2e0*F[0][1]*v[153]+F[0][2]*v[183]+F[0][0]*v[254];
9056 v[179]=v[132]*v[326]+v[37]*(2e0*v[214]+2e0*v[255]-2e0*v[24]*v[57]);
9057 v[178]=v[131]*v[326]+2e0*(-(F[0][1]*v[15])+F[0][0]*v[18])*v[37];
9058 v[167]=v[137]*v[333]-v[338];
9059 v[303]=2e0*F[1][0]*v[167]+F[1][2]*v[231]+F[1][1]*v[272];
9060 v[281]=2e0*F[0][0]*v[167]+F[0][2]*v[231]+F[0][1]*v[272];
9061 v[166]=v[136]*v[333]-v[339];
9062 v[302]=2e0*F[1][0]*v[166]+F[1][2]*v[227]+F[1][1]*v[267];
9063 v[280]=2e0*F[0][0]*v[166]+F[0][2]*v[227]+F[0][1]*v[267];
9064 v[164]=v[134]*v[333]-v[340];
9065 v[278]=2e0*F[0][0]*v[164]+F[0][2]*v[220]+F[0][1]*v[259];
9066 v[163]=v[133]*v[333]-v[341];
9067 v[277]=2e0*F[0][0]*v[163]+F[0][2]*v[216]+F[0][1]*v[254];
9068 v[157]=v[137]*v[148]-v[342];
9069 v[309]=2e0*F[1][1]*v[157]+F[1][2]*v[196]+F[1][0]*v[272];
9070 v[289]=2e0*F[0][1]*v[157]+F[0][2]*v[196]+F[0][0]*v[272];
9071 v[155]=v[135]*v[148]-v[343];
9072 v[307]=2e0*F[1][1]*v[155]+F[1][2]*v[188]+F[1][0]*v[263];
9073 v[287]=2e0*F[0][1]*v[155]+F[0][2]*v[188]+F[0][0]*v[263];
9074 v[154]=v[134]*v[148]-v[344];
9075 v[286]=2e0*F[0][1]*v[154]+F[0][2]*v[187]+F[0][0]*v[259];
9076 v[284]=F[0][2]*v[179]+F[0][0]*v[250]+2e0*F[0][1]*(v[132]*v[148]-v[345]);
9077 v[146]=v[136]*v[138]-v[346];
9078 v[313]=2e0*F[1][2]*v[146]+F[1][1]*v[192]+F[1][0]*v[227];
9079 v[295]=2e0*F[0][2]*v[146]+F[0][1]*v[192]+F[0][0]*v[227];
9080 v[145]=v[135]*v[138]-v[347];
9081 v[312]=2e0*F[1][2]*v[145]+F[1][1]*v[188]+F[1][0]*v[224];
9082 v[294]=2e0*F[0][2]*v[145]+F[0][1]*v[188]+F[0][0]*v[224];
9083 v[292]=F[0][1]*v[183]+F[0][0]*v[216]+2e0*F[0][2]*(v[133]*v[138]-v[348]);
9084 v[291]=F[0][1]*v[179]+F[0][0]*v[213]+(v[132]*v[138]-v[349])*v[356];
9085 v[35]=v[36]+v[138]*v[37];
9087 v[40]=v[36]+v[148]*v[37];
9089 v[43]=v[36]+v[333]*v[37];
9092 v[319]=2e0*F[2][1]*v[157]+F[2][2]*v[196]+F[2][0]*v[272]+v[44];
9093 v[306]=2e0*F[1][1]*v[154]+F[1][2]*v[187]+F[1][0]*v[259]+v[44];
9094 v[283]=F[0][2]*v[178]+F[0][0]*v[246]+v[354]*(v[131]*v[148]+v[355])+v[44];
9096 v[317]=2e0*F[2][0]*v[167]+F[2][2]*v[231]+F[2][1]*v[272]+v[45];
9097 v[300]=2e0*F[1][0]*v[164]+F[1][2]*v[220]+F[1][1]*v[259]+v[45];
9098 v[275]=F[0][2]*v[209]+F[0][1]*v[246]+2e0*F[0][0]*(v[131]*v[333]+v[352])+v[45];
9100 v[316]=2e0*F[2][0]*v[166]+F[2][2]*v[227]+F[2][1]*v[267]+v[46];
9101 v[299]=2e0*F[1][0]*v[163]+F[1][2]*v[216]+F[1][1]*v[254]+v[46];
9102 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]*
9103 (2e0*F[0][2]*v[18]+2e0*v[244]-2e0*v[22]*v[65]));
9104 Pmat[0][0]=F[0][0]*v[297]+F[0][2]*v[45]+F[0][1]*v[46];
9105 Pmat[0][1]=F[0][1]*v[304]+F[0][2]*v[44]+F[0][0]*v[46];
9106 Pmat[0][2]=F[0][2]*v[310]+F[0][1]*v[44]+F[0][0]*v[45];
9107 Pmat[1][0]=2e0*F[1][0]*v[43]+F[1][2]*v[45]+F[1][1]*v[46];
9108 Pmat[1][1]=2e0*F[1][1]*v[40]+F[1][2]*v[44]+F[1][0]*v[46];
9109 Pmat[1][2]=2e0*F[1][2]*v[35]+F[1][1]*v[44]+F[1][0]*v[45];
9110 Pmat[2][0]=F[2][0]*v[297]+F[2][2]*v[45]+F[2][1]*v[46];
9111 Pmat[2][1]=F[2][1]*v[304]+F[2][2]*v[44]+F[2][0]*v[46];
9112 Pmat[2][2]=F[2][2]*v[310]+F[2][1]*v[44]+F[2][0]*v[45];
9113 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]
9115 Amat[0][0][0][1]=v[274];
9116 Amat[0][0][0][2]=v[275];
9117 Amat[0][0][1][0]=v[276];
9118 Amat[0][0][1][1]=v[277];
9119 Amat[0][0][1][2]=v[278];
9120 Amat[0][0][2][0]=v[279];
9121 Amat[0][0][2][1]=v[280];
9122 Amat[0][0][2][2]=v[281];
9123 Amat[0][1][0][0]=v[274];
9124 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]);
9125 Amat[0][1][0][2]=v[283];
9126 Amat[0][1][1][0]=v[284];
9127 Amat[0][1][1][1]=v[285];
9128 Amat[0][1][1][2]=v[286];
9129 Amat[0][1][2][0]=v[287];
9130 Amat[0][1][2][1]=v[288];
9131 Amat[0][1][2][2]=v[289];
9132 Amat[0][2][0][0]=v[275];
9133 Amat[0][2][0][1]=v[283];
9134 Amat[0][2][0][2]=F[0][1]*v[178]+F[0][0]*v[209]+v[310]+v[131]*v[138]*v[356];
9135 Amat[0][2][1][0]=v[291];
9136 Amat[0][2][1][1]=v[292];
9137 Amat[0][2][1][2]=v[293];
9138 Amat[0][2][2][0]=v[294];
9139 Amat[0][2][2][1]=v[295];
9140 Amat[0][2][2][2]=v[296];
9141 Amat[1][0][0][0]=v[276];
9142 Amat[1][0][0][1]=v[284];
9143 Amat[1][0][0][2]=v[291];
9144 Amat[1][0][1][0]=2e0*F[1][0]*v[162]+F[1][2]*v[213]+F[1][1]*v[250]+v[297];
9145 Amat[1][0][1][1]=v[299];
9146 Amat[1][0][1][2]=v[300];
9147 Amat[1][0][2][0]=v[301];
9148 Amat[1][0][2][1]=v[302];
9149 Amat[1][0][2][2]=v[303];
9150 Amat[1][1][0][0]=v[277];
9151 Amat[1][1][0][1]=v[285];
9152 Amat[1][1][0][2]=v[292];
9153 Amat[1][1][1][0]=v[299];
9154 Amat[1][1][1][1]=2e0*F[1][1]*v[153]+F[1][2]*v[183]+F[1][0]*v[254]+v[304];
9155 Amat[1][1][1][2]=v[306];
9156 Amat[1][1][2][0]=v[307];
9157 Amat[1][1][2][1]=v[308];
9158 Amat[1][1][2][2]=v[309];
9159 Amat[1][2][0][0]=v[278];
9160 Amat[1][2][0][1]=v[286];
9161 Amat[1][2][0][2]=v[293];
9162 Amat[1][2][1][0]=v[300];
9163 Amat[1][2][1][1]=v[306];
9164 Amat[1][2][1][2]=2e0*F[1][2]*v[144]+F[1][1]*v[187]+F[1][0]*v[220]+v[310];
9165 Amat[1][2][2][0]=v[312];
9166 Amat[1][2][2][1]=v[313];
9167 Amat[1][2][2][2]=v[314];
9168 Amat[2][0][0][0]=v[279];
9169 Amat[2][0][0][1]=v[287];
9170 Amat[2][0][0][2]=v[294];
9171 Amat[2][0][1][0]=v[301];
9172 Amat[2][0][1][1]=v[307];
9173 Amat[2][0][1][2]=v[312];
9174 Amat[2][0][2][0]=2e0*F[2][0]*v[165]+F[2][2]*v[224]+F[2][1]*v[263]+v[297];
9175 Amat[2][0][2][1]=v[316];
9176 Amat[2][0][2][2]=v[317];
9177 Amat[2][1][0][0]=v[280];
9178 Amat[2][1][0][1]=v[288];
9179 Amat[2][1][0][2]=v[295];
9180 Amat[2][1][1][0]=v[302];
9181 Amat[2][1][1][1]=v[308];
9182 Amat[2][1][1][2]=v[313];
9183 Amat[2][1][2][0]=v[316];
9184 Amat[2][1][2][1]=2e0*F[2][1]*v[156]+F[2][2]*v[192]+F[2][0]*v[267]+v[304];
9185 Amat[2][1][2][2]=v[319];
9186 Amat[2][2][0][0]=v[281];
9187 Amat[2][2][0][1]=v[289];
9188 Amat[2][2][0][2]=v[296];
9189 Amat[2][2][1][0]=v[303];
9190 Amat[2][2][1][1]=v[309];
9191 Amat[2][2][1][2]=v[314];
9192 Amat[2][2][2][0]=v[317];
9193 Amat[2][2][2][1]=v[319];
9194 Amat[2][2][2][2]=2e0*F[2][2]*v[147]+F[2][1]*v[196]+F[2][0]*v[231]+v[310];
9211template <
class SC,
class LO,
class GO,
class NO>
9212void FE<SC,LO,GO,NO>::mr3d(
double* v,
double (*E),
double (*Nu),
double (*C)
9213 ,
double** F,
double** Pmat,
double**** Amat)
9217 v[4]=(*E)/(2e0+2e0*(*Nu));
9218 v[139]=((*C)*v[4])/2e0;
9219 v[5]=(*E)/(3e0-6e0*(*Nu));
9221 v[150]=v[139]*v[57];
9223 v[165]=v[139]*v[66];
9225 v[167]=v[139]*v[87];
9227 v[155]=v[139]*v[58];
9229 v[170]=v[139]*v[67];
9231 v[172]=v[139]*v[88];
9233 v[159]=v[139]*v[59];
9235 v[175]=v[139]*v[68];
9236 v[18]=F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1];
9237 v[345]=(v[18]*v[18]);
9239 v[177]=v[139]*v[89];
9240 v[24]=F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2];
9241 v[344]=(v[24]*v[24]);
9243 v[22]=F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2];
9244 v[15]=Power(F[0][0],2)+Power(F[1][0],2)+Power(F[2][0],2);
9245 v[239]=-(F[2][1]*v[18]);
9246 v[236]=F[2][2]*v[18];
9247 v[228]=-(F[1][1]*v[18]);
9248 v[225]=F[1][2]*v[18];
9249 v[205]=-(F[2][0]*v[18]);
9250 v[196]=-(F[1][0]*v[18]);
9251 v[279]=F[2][1]*v[22];
9252 v[275]=-(F[2][2]*v[22]);
9253 v[266]=F[1][1]*v[22];
9254 v[262]=-(F[1][2]*v[22]);
9255 v[201]=-(F[2][0]*v[22]);
9256 v[192]=-(F[1][0]*v[22]);
9257 v[183]=-(F[0][0]*v[22]);
9258 v[20]=Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2);
9259 v[334]=-(v[20]*v[22]);
9260 v[337]=2e0*(v[334]+v[335]);
9264 v[140]=v[15]*v[20]-v[345];
9265 v[281]=F[2][0]*v[24];
9266 v[271]=-(F[2][2]*v[24]);
9267 v[268]=F[1][0]*v[24];
9268 v[258]=-(F[1][2]*v[24]);
9269 v[255]=F[0][0]*v[24];
9270 v[243]=-(F[0][2]*v[24]);
9271 v[233]=-(F[2][1]*v[24]);
9272 v[222]=-(F[1][1]*v[24]);
9273 v[209]=-(F[0][1]*v[24]);
9274 v[179]=v[18]*v[22]-v[15]*v[24];
9278 v[38]=-(v[22]*v[22]);
9279 v[26]=Power(F[0][2],2)+Power(F[1][2],2)+Power(F[2][2],2);
9280 v[343]=v[20]*v[26]-v[344];
9281 v[361]=v[343]*v[57];
9282 v[247]=v[22]*v[24]-v[18]*v[26];
9291 v[151]=v[15]*v[26]+v[38];
9292 v[29]=v[151]*v[20]+2e0*v[22]*v[335]-v[15]*v[344]-v[26]*v[345];
9293 v[346]=1e0/Power(v[29],2);
9294 v[33]=-2e0*v[139]-v[4]+v[5]*std::log(std::sqrt(v[29]));
9295 v[347]=v[346]*(-v[33]/2e0+v[5]/4e0);
9296 v[138]=v[347]*(F[2][1]*v[336]+F[2][0]*v[337]-v[345]*v[89]+v[15]*v[95]);
9297 v[149]=v[138]*v[140];
9298 v[137]=v[347]*(F[2][2]*v[339]+F[2][0]*v[340]+v[38]*v[68]+v[15]*v[94]);
9299 v[161]=v[137]*v[151];
9300 v[136]=v[347]*(v[100]*v[20]+F[2][2]*v[337]+F[2][1]*v[338]-v[344]*v[59]);
9301 v[174]=v[136]*v[343];
9302 v[135]=v[347]*(F[1][1]*v[336]+F[1][0]*v[337]-v[345]*v[88]+v[15]*v[93]);
9303 v[146]=v[135]*v[140];
9304 v[134]=v[347]*(F[1][2]*v[341]+F[1][0]*v[342]+v[38]*v[67]+v[15]*v[92]);
9305 v[157]=v[134]*v[151];
9306 v[133]=v[347]*(F[1][2]*v[337]+F[1][1]*v[338]-v[344]*v[58]+v[20]*v[98]);
9307 v[169]=v[133]*v[343];
9308 v[132]=v[347]*(F[0][0]*v[337]+F[0][1]*v[339]-v[345]*v[87]+v[15]*v[91]);
9309 v[131]=v[347]*(F[0][2]*v[341]+F[0][0]*v[342]+v[38]*v[66]+v[15]*v[90]);
9310 v[129]=v[347]*(F[0][2]*v[337]+F[0][1]*v[340]+v[361]);
9311 v[37]=v[33]/(2e0*v[29]);
9312 v[365]=v[37]*(2e0*v[183]+v[15]*v[87]);
9313 v[363]=v[37]*(2e0*v[243]+v[90]);
9314 v[362]=v[37]*(2e0*v[209]+v[91]);
9315 v[359]=-2e0*(F[1][0]*v[20]+v[228])*v[37];
9316 v[358]=-(v[37]*(2e0*v[196]+v[15]*v[67]));
9317 v[357]=-2e0*(F[2][0]*v[20]+v[239])*v[37];
9318 v[356]=-(v[37]*(2e0*v[205]+v[15]*v[68]));
9319 v[355]=-(v[37]*(2e0*v[262]+v[98]));
9320 v[354]=-(v[37]*(2e0*v[192]+v[15]*v[88]));
9321 v[353]=-((v[100]+2e0*v[275])*v[37]);
9322 v[352]=-(v[37]*(2e0*v[201]+v[15]*v[89]));
9323 v[351]=-(v[37]*(2e0*v[258]+v[92]));
9324 v[350]=-(v[37]*(2e0*v[222]+v[93]));
9325 v[349]=-(v[37]*(2e0*v[271]+v[94]));
9326 v[348]=-(v[37]*(2e0*v[233]+v[95]));
9327 v[283]=v[138]*v[338]+v[37]*(2e0*v[279]+2e0*v[281]-2e0*v[18]*v[89]);
9328 v[278]=-v[159]+v[137]*v[338]+v[353];
9329 v[274]=-v[175]+v[136]*v[338]+v[349];
9330 v[270]=v[135]*v[338]+v[37]*(2e0*v[266]+2e0*v[268]-2e0*v[18]*v[88]);
9331 v[265]=-v[155]+v[134]*v[338]+v[355];
9332 v[261]=-v[170]+v[133]*v[338]+v[351];
9333 v[257]=v[132]*v[338]+v[37]*(2e0*F[0][1]*v[22]+2e0*v[255]-2e0*v[18]*v[87]);
9334 v[252]=-v[150]+v[131]*v[338]+2e0*(F[0][2]*v[22]-F[0][0]*v[26])*v[37];
9335 v[242]=-v[159]+v[138]*v[337]+v[357];
9336 v[238]=v[137]*v[337]+v[37]*(2e0*v[236]+2e0*v[281]-2e0*v[22]*v[68]);
9337 v[235]=-v[177]+v[136]*v[337]+v[348];
9338 v[312]=2e0*F[1][0]*v[174]+F[1][2]*v[235]+F[1][1]*v[274];
9339 v[290]=2e0*F[0][0]*v[174]+F[0][2]*v[235]+F[0][1]*v[274];
9340 v[231]=-v[155]+v[135]*v[337]+v[359];
9341 v[227]=v[134]*v[337]+v[37]*(2e0*v[225]+2e0*v[268]-2e0*v[22]*v[67]);
9342 v[224]=-v[172]+v[133]*v[337]+v[350];
9343 v[287]=2e0*F[0][0]*v[169]+F[0][2]*v[224]+F[0][1]*v[261];
9344 v[220]=-v[150]+v[132]*v[337]+2e0*(F[0][1]*v[18]-F[0][0]*v[20])*v[37];
9345 v[207]=-v[175]+v[138]*v[336]+v[356];
9346 v[325]=2e0*F[1][2]*v[149]+F[1][1]*v[207]+F[1][0]*v[242];
9347 v[307]=2e0*F[0][2]*v[149]+F[0][1]*v[207]+F[0][0]*v[242];
9348 v[203]=-v[177]+v[137]*v[336]+v[352];
9349 v[319]=2e0*F[1][1]*v[161]+F[1][2]*v[203]+F[1][0]*v[278];
9350 v[299]=2e0*F[0][1]*v[161]+F[0][2]*v[203]+F[0][0]*v[278];
9351 v[199]=v[136]*v[336]+v[37]*(2e0*v[236]+2e0*v[279]-2e0*v[24]*v[59]);
9352 v[198]=-v[170]+v[135]*v[336]+v[358];
9353 v[304]=2e0*F[0][2]*v[146]+F[0][1]*v[198]+F[0][0]*v[231];
9354 v[194]=-v[172]+v[134]*v[336]+v[354];
9355 v[296]=2e0*F[0][1]*v[157]+F[0][2]*v[194]+F[0][0]*v[265];
9356 v[190]=v[133]*v[336]+v[37]*(2e0*v[225]+2e0*v[266]-2e0*v[24]*v[58]);
9357 v[189]=-v[165]+v[132]*v[336]+2e0*(-(F[0][1]*v[15])+F[0][0]*v[18])*v[37];
9358 v[178]=v[177]+v[138]*v[343]-v[348];
9359 v[314]=2e0*F[1][0]*v[178]+F[1][2]*v[242]+F[1][1]*v[283];
9360 v[292]=2e0*F[0][0]*v[178]+F[0][2]*v[242]+F[0][1]*v[283];
9361 v[176]=v[175]+v[137]*v[343]-v[349];
9362 v[313]=2e0*F[1][0]*v[176]+F[1][2]*v[238]+F[1][1]*v[278];
9363 v[291]=2e0*F[0][0]*v[176]+F[0][2]*v[238]+F[0][1]*v[278];
9364 v[173]=v[172]+v[135]*v[343]-v[350];
9365 v[289]=2e0*F[0][0]*v[173]+F[0][2]*v[231]+F[0][1]*v[270];
9366 v[171]=v[170]+v[134]*v[343]-v[351];
9367 v[288]=2e0*F[0][0]*v[171]+F[0][2]*v[227]+F[0][1]*v[265];
9368 v[162]=v[138]*v[151]+v[177]-v[352];
9369 v[320]=2e0*F[1][1]*v[162]+F[1][2]*v[207]+F[1][0]*v[283];
9370 v[300]=2e0*F[0][1]*v[162]+F[0][2]*v[207]+F[0][0]*v[283];
9371 v[160]=v[136]*v[151]+v[159]-v[353];
9372 v[318]=2e0*F[1][1]*v[160]+F[1][2]*v[199]+F[1][0]*v[274];
9373 v[298]=2e0*F[0][1]*v[160]+F[0][2]*v[199]+F[0][0]*v[274];
9374 v[158]=v[135]*v[151]+v[172]-v[354];
9375 v[297]=2e0*F[0][1]*v[158]+F[0][2]*v[198]+F[0][0]*v[270];
9376 v[295]=F[0][2]*v[190]+F[0][0]*v[261]+2e0*F[0][1]*(v[133]*v[151]+v[155]-v[355]);
9377 v[148]=v[137]*v[140]+v[175]-v[356];
9378 v[324]=2e0*F[1][2]*v[148]+F[1][1]*v[203]+F[1][0]*v[238];
9379 v[306]=2e0*F[0][2]*v[148]+F[0][1]*v[203]+F[0][0]*v[238];
9380 v[147]=v[136]*v[140]+v[159]-v[357];
9381 v[323]=2e0*F[1][2]*v[147]+F[1][1]*v[199]+F[1][0]*v[235];
9382 v[305]=2e0*F[0][2]*v[147]+F[0][1]*v[199]+F[0][0]*v[235];
9383 v[303]=F[0][1]*v[194]+F[0][0]*v[227]+2e0*F[0][2]*(v[134]*v[140]+v[170]-v[358]);
9384 v[302]=F[0][1]*v[190]+F[0][0]*v[224]+(v[133]*v[140]+v[155]-v[359])*v[366];
9385 v[36]=v[140]*v[37]+((1e0+(*C)*(-1e0+v[15]+v[20]))*v[4])/2e0;
9387 v[40]=v[151]*v[37]+((1e0+(*C)*(-1e0+v[15]+v[26]))*v[4])/2e0;
9389 v[43]=v[343]*v[37]+((1e0+(*C)*(-1e0+v[20]+v[26]))*v[4])/2e0;
9391 v[45]=-2e0*v[139]*v[24]+v[336]*v[37];
9392 v[330]=2e0*F[2][1]*v[162]+F[2][2]*v[207]+F[2][0]*v[283]+v[45];
9393 v[317]=2e0*F[1][1]*v[158]+F[1][2]*v[198]+F[1][0]*v[270]+v[45];
9394 v[294]=F[0][2]*v[189]+F[0][0]*v[257]+v[364]*(v[132]*v[151]+v[167]+v[365])+v[45];
9395 v[46]=-2e0*v[139]*v[22]+v[337]*v[37];
9396 v[328]=2e0*F[2][0]*v[178]+F[2][2]*v[242]+F[2][1]*v[283]+v[46];
9397 v[311]=2e0*F[1][0]*v[173]+F[1][2]*v[231]+F[1][1]*v[270]+v[46];
9398 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];
9399 v[47]=-2e0*v[139]*v[18]+v[338]*v[37];
9400 v[327]=2e0*F[2][0]*v[176]+F[2][2]*v[238]+F[2][1]*v[278]+v[47];
9401 v[310]=2e0*F[1][0]*v[171]+F[1][2]*v[227]+F[1][1]*v[265]+v[47];
9402 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]*
9403 (2e0*F[0][2]*v[18]+2e0*v[255]-2e0*v[22]*v[66]));
9404 Pmat[0][0]=F[0][0]*v[308]+F[0][2]*v[46]+F[0][1]*v[47];
9405 Pmat[0][1]=F[0][1]*v[315]+F[0][2]*v[45]+F[0][0]*v[47];
9406 Pmat[0][2]=F[0][2]*v[321]+F[0][1]*v[45]+F[0][0]*v[46];
9407 Pmat[1][0]=2e0*F[1][0]*v[43]+F[1][2]*v[46]+F[1][1]*v[47];
9408 Pmat[1][1]=2e0*F[1][1]*v[40]+F[1][2]*v[45]+F[1][0]*v[47];
9409 Pmat[1][2]=2e0*F[1][2]*v[36]+F[1][1]*v[45]+F[1][0]*v[46];
9410 Pmat[2][0]=F[2][0]*v[308]+F[2][2]*v[46]+F[2][1]*v[47];
9411 Pmat[2][1]=F[2][1]*v[315]+F[2][2]*v[45]+F[2][0]*v[47];
9412 Pmat[2][2]=F[2][2]*v[321]+F[2][1]*v[45]+F[2][0]*v[46];
9413 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]
9414 +v[129]*v[338]-v[363]);
9415 Amat[0][0][0][1]=v[285];
9416 Amat[0][0][0][2]=v[286];
9417 Amat[0][0][1][0]=v[287];
9418 Amat[0][0][1][1]=v[288];
9419 Amat[0][0][1][2]=v[289];
9420 Amat[0][0][2][0]=v[290];
9421 Amat[0][0][2][1]=v[291];
9422 Amat[0][0][2][2]=v[292];
9423 Amat[0][1][0][0]=v[285];
9424 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]);
9425 Amat[0][1][0][2]=v[294];
9426 Amat[0][1][1][0]=v[295];
9427 Amat[0][1][1][1]=v[296];
9428 Amat[0][1][1][2]=v[297];
9429 Amat[0][1][2][0]=v[298];
9430 Amat[0][1][2][1]=v[299];
9431 Amat[0][1][2][2]=v[300];
9432 Amat[0][2][0][0]=v[286];
9433 Amat[0][2][0][1]=v[294];
9434 Amat[0][2][0][2]=F[0][1]*v[189]+F[0][0]*v[220]+v[321]+v[132]*v[140]*v[366];
9435 Amat[0][2][1][0]=v[302];
9436 Amat[0][2][1][1]=v[303];
9437 Amat[0][2][1][2]=v[304];
9438 Amat[0][2][2][0]=v[305];
9439 Amat[0][2][2][1]=v[306];
9440 Amat[0][2][2][2]=v[307];
9441 Amat[1][0][0][0]=v[287];
9442 Amat[1][0][0][1]=v[295];
9443 Amat[1][0][0][2]=v[302];
9444 Amat[1][0][1][0]=2e0*F[1][0]*v[169]+F[1][2]*v[224]+F[1][1]*v[261]+v[308];
9445 Amat[1][0][1][1]=v[310];
9446 Amat[1][0][1][2]=v[311];
9447 Amat[1][0][2][0]=v[312];
9448 Amat[1][0][2][1]=v[313];
9449 Amat[1][0][2][2]=v[314];
9450 Amat[1][1][0][0]=v[288];
9451 Amat[1][1][0][1]=v[296];
9452 Amat[1][1][0][2]=v[303];
9453 Amat[1][1][1][0]=v[310];
9454 Amat[1][1][1][1]=2e0*F[1][1]*v[157]+F[1][2]*v[194]+F[1][0]*v[265]+v[315];
9455 Amat[1][1][1][2]=v[317];
9456 Amat[1][1][2][0]=v[318];
9457 Amat[1][1][2][1]=v[319];
9458 Amat[1][1][2][2]=v[320];
9459 Amat[1][2][0][0]=v[289];
9460 Amat[1][2][0][1]=v[297];
9461 Amat[1][2][0][2]=v[304];
9462 Amat[1][2][1][0]=v[311];
9463 Amat[1][2][1][1]=v[317];
9464 Amat[1][2][1][2]=2e0*F[1][2]*v[146]+F[1][1]*v[198]+F[1][0]*v[231]+v[321];
9465 Amat[1][2][2][0]=v[323];
9466 Amat[1][2][2][1]=v[324];
9467 Amat[1][2][2][2]=v[325];
9468 Amat[2][0][0][0]=v[290];
9469 Amat[2][0][0][1]=v[298];
9470 Amat[2][0][0][2]=v[305];
9471 Amat[2][0][1][0]=v[312];
9472 Amat[2][0][1][1]=v[318];
9473 Amat[2][0][1][2]=v[323];
9474 Amat[2][0][2][0]=2e0*F[2][0]*v[174]+F[2][2]*v[235]+F[2][1]*v[274]+v[308];
9475 Amat[2][0][2][1]=v[327];
9476 Amat[2][0][2][2]=v[328];
9477 Amat[2][1][0][0]=v[291];
9478 Amat[2][1][0][1]=v[299];
9479 Amat[2][1][0][2]=v[306];
9480 Amat[2][1][1][0]=v[313];
9481 Amat[2][1][1][1]=v[319];
9482 Amat[2][1][1][2]=v[324];
9483 Amat[2][1][2][0]=v[327];
9484 Amat[2][1][2][1]=2e0*F[2][1]*v[161]+F[2][2]*v[203]+F[2][0]*v[278]+v[315];
9485 Amat[2][1][2][2]=v[330];
9486 Amat[2][2][0][0]=v[292];
9487 Amat[2][2][0][1]=v[300];
9488 Amat[2][2][0][2]=v[307];
9489 Amat[2][2][1][0]=v[314];
9490 Amat[2][2][1][1]=v[320];
9491 Amat[2][2][1][2]=v[325];
9492 Amat[2][2][2][0]=v[328];
9493 Amat[2][2][2][1]=v[330];
9494 Amat[2][2][2][2]=2e0*F[2][2]*v[149]+F[2][1]*v[207]+F[2][0]*v[242]+v[321];
9511template <
class SC,
class LO,
class GO,
class NO>
9512void FE<SC,LO,GO,NO>::stvk3d(
double* v,
double (*lam),
double (*mue),
double** F
9513 ,
double** Pmat,
double**** Amat)
9515 v[169]=Power(F[0][0],2);
9517 v[167]=Power(F[0][2],2);
9518 v[166]=F[2][2]*(*mue);
9519 v[165]=F[2][1]*(*mue);
9520 v[164]=F[2][0]*(*mue);
9521 v[163]=F[1][2]*(*mue);
9522 v[162]=F[1][1]*(*mue);
9523 v[161]=F[1][0]*(*mue);
9524 v[88]=F[0][0]*(*mue);
9525 v[116]=F[0][0]*v[88];
9526 v[70]=F[0][1]*(*lam);
9527 v[93]=F[0][1]*(*mue);
9528 v[117]=F[0][1]*v[93];
9529 v[71]=F[0][2]*(*lam);
9530 v[105]=(*mue)*v[167];
9531 v[72]=F[1][0]*(*lam);
9532 v[85]=2e0*v[161]+v[72];
9533 v[142]=F[1][0]*v[161];
9534 v[121]=F[0][0]*v[161];
9535 v[73]=F[1][1]*(*lam);
9536 v[100]=F[0][1]*v[161]+F[0][0]*v[73];
9537 v[82]=2e0*v[162]+v[73];
9538 v[143]=F[1][1]*v[162];
9539 v[122]=F[0][1]*v[162];
9540 v[108]=F[0][0]*v[162]+F[0][1]*v[72];
9541 v[74]=F[1][2]*(*lam);
9542 v[111]=F[0][2]*v[162]+F[0][1]*v[74];
9543 v[101]=F[0][2]*v[161]+F[0][0]*v[74];
9544 v[79]=2e0*v[163]+v[74];
9545 v[123]=v[121]+v[122]+F[0][2]*v[79];
9546 v[135]=F[1][2]*v[163];
9547 v[120]=F[0][1]*v[163]+F[0][2]*v[73];
9548 v[119]=F[0][0]*v[163]+F[0][2]*v[72];
9549 v[109]=F[0][2]*v[163];
9550 v[110]=v[109]+v[121]+F[0][1]*v[82];
9551 v[99]=v[109]+v[122]+F[0][0]*v[85];
9552 v[75]=F[2][0]*(*lam);
9553 v[86]=2e0*v[164]+v[75];
9554 v[156]=F[2][0]*v[164];
9555 v[147]=F[1][0]*v[164];
9556 v[126]=F[0][0]*v[164];
9557 v[76]=F[2][1]*(*lam);
9558 v[133]=F[1][1]*v[164]+F[1][0]*v[76];
9559 v[103]=F[0][1]*v[164]+F[0][0]*v[76];
9560 v[83]=2e0*v[165]+v[76];
9561 v[157]=F[2][1]*v[165];
9562 v[148]=F[1][1]*v[165];
9563 v[138]=F[1][0]*v[165]+F[1][1]*v[75];
9564 v[127]=F[0][1]*v[165];
9565 v[112]=F[0][0]*v[165]+F[0][1]*v[75];
9566 v[77]=F[2][2]*(*lam);
9567 v[141]=F[1][2]*v[165]+F[1][1]*v[77];
9568 v[134]=F[1][2]*v[164]+F[1][0]*v[77];
9569 v[115]=F[0][2]*v[165]+F[0][1]*v[77];
9570 v[104]=F[0][2]*v[164]+F[0][0]*v[77];
9571 v[80]=2e0*v[166]+v[77];
9572 v[149]=v[147]+v[148]+F[1][2]*v[80];
9573 v[128]=v[126]+v[127]+F[0][2]*v[80];
9574 v[153]=F[2][2]*v[166];
9575 v[146]=F[1][1]*v[166]+F[1][2]*v[76];
9576 v[145]=F[1][0]*v[166]+F[1][2]*v[75];
9577 v[139]=F[1][2]*v[166];
9578 v[140]=v[139]+v[147]+F[1][1]*v[83];
9579 v[132]=v[139]+v[148]+F[1][0]*v[86];
9580 v[125]=F[0][1]*v[166]+F[0][2]*v[76];
9581 v[124]=F[0][0]*v[166]+F[0][2]*v[75];
9582 v[113]=F[0][2]*v[166];
9583 v[114]=v[113]+v[126]+F[0][1]*v[83];
9584 v[102]=v[113]+v[127]+F[0][0]*v[86];
9585 v[24]=(-1e0+Power(F[1][0],2)+Power(F[2][0],2)+v[169])/2e0;
9586 v[28]=(-1e0+Power(F[0][1],2)+Power(F[1][1],2)+Power(F[2][1],2))/2e0;
9587 v[32]=(-1e0+Power(F[1][2],2)+Power(F[2][2],2)+v[167])/2e0;
9588 v[36]=(*lam)*(v[24]+v[28]+v[32]);
9589 v[35]=2e0*(*mue)*v[32]+v[36];
9590 v[37]=2e0*(*mue)*v[28]+v[36];
9591 v[38]=2e0*(*mue)*v[24]+v[36];
9592 v[39]=(F[0][0]*F[0][2]+F[1][0]*F[1][2]+F[2][0]*F[2][2])*(*mue);
9593 v[152]=F[2][2]*v[164]+v[39]+F[2][0]*v[77];
9594 v[131]=F[1][2]*v[161]+v[39]+F[1][0]*v[74];
9595 v[98]=v[39]+F[0][0]*v[71]+F[0][2]*v[88];
9596 v[40]=(F[0][1]*F[0][2]+F[1][1]*F[1][2]+F[2][1]*F[2][2])*(*mue);
9597 v[155]=F[2][2]*v[165]+v[40]+F[2][1]*v[77];
9598 v[137]=F[1][2]*v[162]+v[40]+F[1][1]*v[74];
9599 v[107]=v[40]+F[0][1]*v[71]+F[0][2]*v[93];
9600 v[41]=(F[0][0]*F[0][1]+F[1][0]*F[1][1]+F[2][0]*F[2][1])*(*mue);
9601 v[151]=F[2][1]*v[164]+v[41]+F[2][0]*v[76];
9602 v[130]=F[1][1]*v[161]+v[41]+F[1][0]*v[73];
9603 v[97]=v[41]+F[0][0]*v[70]+F[0][1]*v[88];
9604 Pmat[0][0]=F[0][0]*v[38]+F[0][2]*v[39]+F[0][1]*v[41];
9605 Pmat[0][1]=F[0][1]*v[37]+F[0][2]*v[40]+F[0][0]*v[41];
9606 Pmat[0][2]=F[0][2]*v[35]+F[0][0]*v[39]+F[0][1]*v[40];
9607 Pmat[1][0]=F[1][0]*v[38]+F[1][2]*v[39]+F[1][1]*v[41];
9608 Pmat[1][1]=F[1][1]*v[37]+F[1][2]*v[40]+F[1][0]*v[41];
9609 Pmat[1][2]=F[1][2]*v[35]+F[1][0]*v[39]+F[1][1]*v[40];
9610 Pmat[2][0]=F[2][0]*v[38]+F[2][2]*v[39]+F[2][1]*v[41];
9611 Pmat[2][1]=F[2][1]*v[37]+F[2][2]*v[40]+F[2][0]*v[41];
9612 Pmat[2][2]=F[2][2]*v[35]+F[2][0]*v[39]+F[2][1]*v[40];
9613 Amat[0][0][0][0]=v[105]+v[117]+((*lam)+v[168])*v[169]+v[38];
9614 Amat[0][0][0][1]=v[97];
9615 Amat[0][0][0][2]=v[98];
9616 Amat[0][0][1][0]=v[99];
9617 Amat[0][0][1][1]=v[100];
9618 Amat[0][0][1][2]=v[101];
9619 Amat[0][0][2][0]=v[102];
9620 Amat[0][0][2][1]=v[103];
9621 Amat[0][0][2][2]=v[104];
9622 Amat[0][1][0][0]=v[97];
9623 Amat[0][1][0][1]=v[105]+v[116]+v[37]+F[0][1]*(v[70]+2e0*v[93]);
9624 Amat[0][1][0][2]=v[107];
9625 Amat[0][1][1][0]=v[108];
9626 Amat[0][1][1][1]=v[110];
9627 Amat[0][1][1][2]=v[111];
9628 Amat[0][1][2][0]=v[112];
9629 Amat[0][1][2][1]=v[114];
9630 Amat[0][1][2][2]=v[115];
9631 Amat[0][2][0][0]=v[98];
9632 Amat[0][2][0][1]=v[107];
9633 Amat[0][2][0][2]=v[116]+v[117]+v[35]+F[0][2]*(F[0][2]*v[168]+v[71]);
9634 Amat[0][2][1][0]=v[119];
9635 Amat[0][2][1][1]=v[120];
9636 Amat[0][2][1][2]=v[123];
9637 Amat[0][2][2][0]=v[124];
9638 Amat[0][2][2][1]=v[125];
9639 Amat[0][2][2][2]=v[128];
9640 Amat[1][0][0][0]=v[99];
9641 Amat[1][0][0][1]=v[108];
9642 Amat[1][0][0][2]=v[119];
9643 Amat[1][0][1][0]=v[135]+v[143]+v[38]+F[1][0]*v[85];
9644 Amat[1][0][1][1]=v[130];
9645 Amat[1][0][1][2]=v[131];
9646 Amat[1][0][2][0]=v[132];
9647 Amat[1][0][2][1]=v[133];
9648 Amat[1][0][2][2]=v[134];
9649 Amat[1][1][0][0]=v[100];
9650 Amat[1][1][0][1]=v[110];
9651 Amat[1][1][0][2]=v[120];
9652 Amat[1][1][1][0]=v[130];
9653 Amat[1][1][1][1]=v[135]+v[142]+v[37]+F[1][1]*v[82];
9654 Amat[1][1][1][2]=v[137];
9655 Amat[1][1][2][0]=v[138];
9656 Amat[1][1][2][1]=v[140];
9657 Amat[1][1][2][2]=v[141];
9658 Amat[1][2][0][0]=v[101];
9659 Amat[1][2][0][1]=v[111];
9660 Amat[1][2][0][2]=v[123];
9661 Amat[1][2][1][0]=v[131];
9662 Amat[1][2][1][1]=v[137];
9663 Amat[1][2][1][2]=v[142]+v[143]+v[35]+F[1][2]*v[79];
9664 Amat[1][2][2][0]=v[145];
9665 Amat[1][2][2][1]=v[146];
9666 Amat[1][2][2][2]=v[149];
9667 Amat[2][0][0][0]=v[102];
9668 Amat[2][0][0][1]=v[112];
9669 Amat[2][0][0][2]=v[124];
9670 Amat[2][0][1][0]=v[132];
9671 Amat[2][0][1][1]=v[138];
9672 Amat[2][0][1][2]=v[145];
9673 Amat[2][0][2][0]=v[153]+v[157]+v[38]+F[2][0]*v[86];
9674 Amat[2][0][2][1]=v[151];
9675 Amat[2][0][2][2]=v[152];
9676 Amat[2][1][0][0]=v[103];
9677 Amat[2][1][0][1]=v[114];
9678 Amat[2][1][0][2]=v[125];
9679 Amat[2][1][1][0]=v[133];
9680 Amat[2][1][1][1]=v[140];
9681 Amat[2][1][1][2]=v[146];
9682 Amat[2][1][2][0]=v[151];
9683 Amat[2][1][2][1]=v[153]+v[156]+v[37]+F[2][1]*v[83];
9684 Amat[2][1][2][2]=v[155];
9685 Amat[2][2][0][0]=v[104];
9686 Amat[2][2][0][1]=v[115];
9687 Amat[2][2][0][2]=v[128];
9688 Amat[2][2][1][0]=v[134];
9689 Amat[2][2][1][1]=v[141];
9690 Amat[2][2][1][2]=v[149];
9691 Amat[2][2][2][0]=v[152];
9692 Amat[2][2][2][1]=v[155];
9693 Amat[2][2][2][2]=v[156]+v[157]+v[35]+F[2][2]*v[80];
9709template <
class SC,
class LO,
class GO,
class NO>
9710void FE<SC,LO,GO,NO>::stvk2d(
double* v,
double (*lam),
double (*mue),
double** F
9711 ,
double** Pmat,
double**** Amat)
9713 v[43]=F[0][0]*F[1][0];
9714 v[42]=F[0][1]*F[1][1];
9715 v[37]=Power(F[0][0],2);
9717 v[36]=Power(F[0][1],2);
9718 v[34]=F[0][0]*F[0][1];
9720 v[27]=Power(F[1][0],2);
9721 v[31]=-1e0+v[27]+v[37];
9723 v[25]=Power(F[1][1],2);
9724 v[26]=-1e0+v[25]+v[36];
9725 v[23]=F[1][0]*F[1][1];
9727 v[35]=(*lam)*v[34]+(*mue)*(v[22]+v[34]);
9728 v[24]=(*lam)*v[23]+(*mue)*(v[22]+v[23]);
9729 v[21]=(*lam)*v[42]+2e0*(*mue)*(2e0*v[12]*v[14]+v[42]);
9730 v[20]=F[0][0]*F[1][1]*(*lam)+4e0*(*mue)*v[11]*v[14];
9732 v[30]=F[0][1]*F[1][0]*(*lam)+4e0*(*mue)*v[12]*v[13];
9733 v[29]=(*lam)*v[43]+2e0*(*mue)*(2e0*v[11]*v[13]+v[43]);
9735 v[32]=((*lam)*(v[26]+v[31]))/2e0;
9736 Pmat[0][0]=F[0][0]*v[32]+(*mue)*(F[0][0]*v[31]+v[11]*v[44]);
9737 Pmat[0][1]=F[0][1]*v[32]+(*mue)*(F[0][1]*v[26]+v[12]*v[44]);
9738 Pmat[1][0]=F[1][0]*v[32]+(*mue)*(F[1][0]*v[31]+v[13]*v[44]);
9739 Pmat[1][1]=F[1][1]*v[32]+(*mue)*(F[1][1]*v[26]+v[14]*v[44]);
9740 Amat[0][0][0][0]=v[32]+(*lam)*v[37]+(*mue)*(v[31]+v[36]+2e0*v[37]);
9741 Amat[0][0][0][1]=v[35];
9742 Amat[0][0][1][0]=v[29];
9743 Amat[0][0][1][1]=v[20];
9744 Amat[0][1][0][0]=v[35];
9745 Amat[0][1][0][1]=v[32]+(*lam)*v[36]+(*mue)*(v[26]+2e0*v[36]+v[37]);
9746 Amat[0][1][1][0]=v[30];
9747 Amat[0][1][1][1]=v[21];
9748 Amat[1][0][0][0]=v[29];
9749 Amat[1][0][0][1]=v[30];
9750 Amat[1][0][1][0]=(*lam)*v[27]+(*mue)*(v[25]+2e0*v[27]+v[31])+v[32];
9751 Amat[1][0][1][1]=v[24];
9752 Amat[1][1][0][0]=v[20];
9753 Amat[1][1][0][1]=v[21];
9754 Amat[1][1][1][0]=v[24];
9755 Amat[1][1][1][1]=(*lam)*v[25]+(*mue)*(2e0*v[25]+v[26]+v[27])+v[32];