inline double FunctionIntegral (const uint vb, MultiLevelProblem & ml_prob, double (*pt2func)(double, const std::vector<double> ) ) { const uint mesh_vb = vb; const uint Level = ml_prob.GetMeshTwo()._NoLevels - 1; const uint myproc = ml_prob.GetMeshTwo()._iproc; double time = 0.; Mesh *mymsh = ml_prob._ml_msh->GetLevel(Level); double integral = 0.; //parallel sum const uint nel_e = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level+1]; const uint nel_b = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level]; for (uint iel=0; iel < (nel_e - nel_b); iel++) { CurrentElem currelem(iel,myproc,Level,vb,NULL,ml_prob.GetMeshTwo(),ml_prob.GetElemType(),mymsh); //element without equation CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); const uint el_ngauss = ml_prob.GetQrule(currelem.GetDim()).GetGaussPointsNumber(); //========= DOMAIN MAPPING CurrentQuantity xyz(currgp); xyz._dim = ml_prob.GetMeshTwo().get_dim(); xyz._FEord = MESH_MAPPING_FE; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); currelem.SetDofobjConnCoords(); currelem.ConvertElemCoordsToMappingOrd(xyz); for (uint qp = 0; qp < el_ngauss; qp++) { for (uint fe = 0; fe < QL; fe++) { currgp.SetPhiElDofsFEVB_g (fe,qp); currgp.SetDPhiDxezetaElDofsFEVB_g (fe,qp); } double Jac_g=0.; if (vb==0) Jac_g = currgp.JacVectVV_g(xyz); //not xyz_refbox! else if (vb==1) Jac_g = currgp.JacVectBB_g(xyz); //not xyz_refbox! const double wgt_g = ml_prob.GetQrule(currelem.GetDim()).GetGaussWeight(qp); xyz.val_g(); double myval_g = pt2func(time,xyz._val_g); integral += wgt_g*Jac_g*myval_g; }//gauss loop }//element loop std::cout << std::endl << " ^^^^^^^^^^^^^^^^^L'integrale sul processore "<< myproc << " vale: " << integral << std::endl; // double weights_sum = 0.; // for (uint qp = 0; qp < el_ngauss; qp++) weights_sum += ml_prob.GetQrule(currelem.GetDim()).GetGaussWeight(qp); // std::cout << std::endl << " ^^^^^^^^^^^^^^^^^ La somma dei pesi vale: " << weights_sum << std::endl; double J=0.; #ifdef HAVE_MPI // MPI_Reduce( &integral, &J, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD ); //This one gives J only to processor 0 ! MPI_Allreduce( &integral, &J, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD ); //THIS IS THE RIGHT ONE!! #else J = integral; #endif std::cout << std::endl << " ^^^^^^^^^^^^^^^^^L'integrale totale vale: " << J << std::endl; return J; }
/// This function assembles the matrix and the rhs: void GenMatRhsT(MultiLevelProblem &ml_prob){ //if we are just a function not inside a class, we have to retrieve ourselves... SystemTwo & my_system = ml_prob.get_system<SystemTwo>("Eqn_T"); const unsigned Level = my_system.GetLevelToAssemble(); // ========================================== Mesh *mymsh = ml_prob._ml_msh->GetLevel(Level); elem *myel = mymsh->el; const unsigned myproc = mymsh->processor_id(); //======== ELEMENT MAPPING ======= const uint space_dim = ml_prob._ml_msh->GetDimension(); //====== reference values ======================== const double IRe = 1./ml_prob.GetInputParser().get("Re"); const double IPr = 1./ml_prob.GetInputParser().get("Pr"); const double alphaT = ml_prob.GetInputParser().get("alphaT"); const double alphaL2 = ml_prob.GetInputParser().get("alphaL2"); const double alphaH1 = ml_prob.GetInputParser().get("alphaH1"); //==== AUXILIARY ============== std::vector<double> dphijdx_g(space_dim); std::vector<double> dphiidx_g(space_dim); my_system._LinSolver[Level]->_KK->zero(); my_system._LinSolver[Level]->_RESC->zero(); // ========================================== // ========================================== {//BEGIN VOLUME const uint mesh_vb = VV; const uint nel_b = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level]; const uint nel_e = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level+1]; // const uint nel_beg = mymsh->_elementOffset[myproc]; // const uint nel_end = mymsh->_elementOffset[myproc+1]; for (uint iel = 0; iel < (nel_e - nel_b); iel++) { // for (uint iel_two = nel_beg; iel_two < nel_end; iel_two++) { CurrentElem<double> currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType(),mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQuadratureRule(currelem.GetDim())); //=========INTERNAL QUANTITIES (unknowns of the equation) ========= CurrentQuantity Tempold(currgp); Tempold._SolName = "Qty_Temperature"; Tempold._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Temperature"); Tempold.VectWithQtyFillBasic(); Tempold.Allocate(); //==================================== CurrentQuantity Tlift(currgp); Tlift._SolName = "Qty_TempLift"; Tlift._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_TempLift"); Tlift.VectWithQtyFillBasic(); Tlift.Allocate(); //===================================== CurrentQuantity TAdj(currgp); TAdj._SolName = "Qty_TempAdj"; TAdj._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_TempAdj"); TAdj.VectWithQtyFillBasic(); TAdj.Allocate(); //=========EXTERNAL QUANTITIES (couplings) ===== //========= //DOMAIN MAPPING CurrentQuantity xyz(currgp); //no quantity xyz._dim = space_dim; xyz._FEord = MESH_MAPPING_FE; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); //================== CurrentQuantity velX(currgp); velX._SolName = "Qty_Velocity0"; velX._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Velocity0"); velX.VectWithQtyFillBasic(); velX.Allocate(); //================== CurrentQuantity velY(currgp); velY._SolName = "Qty_Velocity1"; velY._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Velocity1"); velY.VectWithQtyFillBasic(); velY.Allocate(); //===============Tdes===================== CurrentQuantity Tdes(currgp); Tdes._SolName = "Qty_TempDes"; Tdes._dim = Tempold._dim; Tdes._FEord = Tempold._FEord; Tdes._ndof = Tempold._ndof; Tdes.Allocate(); // ========================================== // ========================================== currelem.Mat().zero(); currelem.Rhs().zero(); currelem.SetDofobjConnCoords(); currelem.SetElDofsBc(); Tempold.GetElemDofs(); Tlift.GetElemDofs(); TAdj.GetElemDofs(); velX.GetElemDofs(); velY.GetElemDofs(); TempDesired(Tdes,currelem); currelem.ConvertElemCoordsToMappingOrd(xyz); xyz.SetElemAverage(); int domain_flag = ElFlagControl(xyz._el_average,ml_prob._ml_msh); //==================== const uint el_ngauss = ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussPointsNumber(); for (uint qp=0; qp< el_ngauss; qp++) { //======= "COMMON SHAPE PART"================== for (uint fe = 0; fe < QL; fe++) { currgp.SetPhiElDofsFEVB_g (fe,qp); currgp.SetDPhiDxezetaElDofsFEVB_g (fe,qp); } const double det = currgp.JacVectVV_g(xyz); const double dtxJxW_g = det*ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussWeight(qp); const double detb = det/el_ngauss; for (uint fe = 0; fe < QL; fe++) { currgp.SetDPhiDxyzElDofsFEVB_g (fe,qp); currgp.ExtendDphiDxyzElDofsFEVB_g(fe); } //======= end of the "COMMON SHAPE PART"================== Tempold.val_g(); Tlift.val_g(); TAdj.val_g(); velX.val_g(); velY.val_g(); Tdes.val_g(); for (uint i=0; i < Tempold._ndof; i++) { const double phii_g = currgp._phi_ndsQLVB_g[Tempold._FEord][i]; for (uint idim = 0; idim < space_dim; idim++) dphiidx_g[idim] = currgp._dphidxyz_ndsQLVB_g[Tempold._FEord][i+idim*Tempold._ndof]; //=========== FIRST ROW =============== currelem.Rhs()(i) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( 0. ) + (1-currelem.GetBCDofFlag()[i])*detb*(Tempold._val_dofs[i]); currelem.Mat()(i,i) += (1-currelem.GetBCDofFlag()[i])*detb; //========= SECOND ROW (CONTROL) ===================== int ip1 = i + /* 1* */Tempold._ndof; //suppose that T' T_0 T_adj have the same order currelem.Rhs()(ip1) += currelem.GetBCDofFlag()[ip1]*dtxJxW_g*( + alphaT*domain_flag*(Tdes._val_g[0])*phii_g // T_d delta T_0 ) + (1-currelem.GetBCDofFlag()[ip1])*detb*(Tlift._val_dofs[i]); currelem.Mat()(ip1,ip1) += (1-currelem.GetBCDofFlag()[ip1])*detb; //======= THIRD ROW (ADJOINT) =================================== int ip2 = i + 2 * Tempold._ndof; //suppose that T' T_0 T_adj have the same order currelem.Rhs()(ip2) += currelem.GetBCDofFlag()[ip2]*dtxJxW_g*( + alphaT*domain_flag*(Tdes._val_g[0])*phii_g // T_d delta T' ) + (1-currelem.GetBCDofFlag()[ip2])*detb*(Tempold._val_dofs[i]); currelem.Mat()(ip2,ip2) += (1-currelem.GetBCDofFlag()[ip2])*detb; // Matrix Assemblying --------------------------- for (uint j=0; j<Tempold._ndof; j++) { double phij_g = currgp._phi_ndsQLVB_g[Tempold._FEord][j]; for (uint idim = 0; idim < space_dim; idim++) dphijdx_g[idim] = currgp._dphidxyz_ndsQLVB_g[Tempold._FEord][j+idim*Tempold._ndof]; double Lap_g = Math::dot(&dphijdx_g[0],&dphiidx_g[0],space_dim); double Advection = velX._val_g[0]*dphijdx_g[0] + velY._val_g[0]*dphijdx_g[1]; //Math::dot(&vel._val_g[0],&dphijdx_g[0],space_dim); int ip1 = i + Tempold._ndof; int jp1 = j + Tempold._ndof; int ip2 = i + 2*Tempold._ndof; int jp2 = j + 2*Tempold._ndof; // T T_0 T_adj // T X X O // T_0 // T_adj //============ FIRST ROW state delta T =============== //======= DIAGONAL ============================= currelem.Mat()(i,j) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( + Advection*phii_g + IRe*IPr*Lap_g ); //=============================== //same operators for T and T_0 currelem.Mat()(i,jp1) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( + Advection*phii_g + IRe*IPr*Lap_g ); //==================================== currelem.Mat()(i,jp2) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( 0. ); //============= SECOND ROW (LIFTING) delta T_0 ============= //===== DIAGONAL =========================== currelem.Mat()(ip1,jp1) += currelem.GetBCDofFlag()[ip1]* dtxJxW_g*( + alphaL2*phij_g*phii_g //L_2 control norm + alphaH1*Lap_g //H_1 control norm + alphaT*domain_flag*(phij_g)*phii_g //T_0 delta T_0 //ADDED/////////////// ); //==================================== currelem.Mat()(ip1,j) += currelem.GetBCDofFlag()[ip1]* dtxJxW_g*( + alphaT*domain_flag*(phij_g)*phii_g //T' delta T_0 //ADDED/////////////// ); //==================================== currelem.Mat()(ip1,jp2) += currelem.GetBCDofFlag()[ip1]* dtxJxW_g*( -Advection*phii_g + IRe*IPr*Lap_g ); //============= THIRD ROW (ADJOINT) ============= //======= DIAGONAL ================== currelem.Mat()(ip2,jp2) += currelem.GetBCDofFlag()[ip2]* dtxJxW_g*( - Advection*phii_g //minus sign + IRe*IPr*Lap_g ); //==================================== currelem.Mat()(ip2,j) += currelem.GetBCDofFlag()[ip2]* dtxJxW_g*( + alphaT*domain_flag*(phij_g)*phii_g //T' delta T' ); //==================================== currelem.Mat()(ip2,jp1) += currelem.GetBCDofFlag()[ip2]* dtxJxW_g*( + alphaT*domain_flag*(phij_g)*phii_g //T_0 delta T' ///ADDED/////// ); } //end j (col) } //end i (row) } // end of the quadrature point qp-loop my_system._LinSolver[Level]->_KK->add_matrix(currelem.Mat(),currelem.GetDofIndices()); my_system._LinSolver[Level]->_RESC->add_vector(currelem.Rhs(),currelem.GetDofIndices()); } // end of element loop // ***************************************************************** }//END VOLUME my_system._LinSolver[Level]->_KK->close(); my_system._LinSolver[Level]->_RESC->close(); #ifdef DEFAULT_PRINT_INFO std::cout << " Matrix and RHS assembled for equation " << my_system.name() << " Level "<< Level << " dofs " << my_system._LinSolver[Level]->_KK->n() << std::endl; #endif return; }
void GenMatRhsT(MultiLevelProblem &ml_prob) { SystemTwo & my_system = ml_prob.get_system<SystemTwo>("Eqn_T"); const unsigned Level = my_system.GetLevelToAssemble(); const double time = 0.; //======== ELEMENT MAPPING ======= const uint space_dim = ml_prob._ml_msh->GetDimension(); my_system._LinSolver[Level]->_KK->zero(); my_system._LinSolver[Level]->_RESC->zero(); // ========================================== Mesh *mymsh = ml_prob._ml_msh->GetLevel(Level); elem *myel = mymsh->el; const unsigned myproc = mymsh->processor_id(); // ========================================== // ========================================== {//BEGIN VOLUME //==== AUXILIARY ============== double* dphijdx_g = new double[space_dim]; double* dphiidx_g = new double[space_dim]; const uint mesh_vb = VV; const uint nel_e = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level+1]; const uint nel_b = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level]; for (uint iel=0; iel < (nel_e - nel_b); iel++) { CurrentElem<double> currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType(),mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQuadratureRule(currelem.GetDim())); //=========INTERNAL QUANTITIES (unknowns of the equation) ========= CurrentQuantity Tempold(currgp); Tempold._qtyptr = my_system.GetUnknownQuantitiesVector()[0]; Tempold.VectWithQtyFillBasic(); Tempold.Allocate(); //=========EXTERNAL QUANTITIES (couplings) ===== //========= //DOMAIN MAPPING CurrentQuantity xyz(currgp); //no quantity xyz._dim = space_dim; xyz._FEord = MESH_MAPPING_FE; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); currelem.Mat().zero(); currelem.Rhs().zero(); currelem.SetDofobjConnCoords(); currelem.SetElDofsBc(); currelem.ConvertElemCoordsToMappingOrd(xyz); Tempold.GetElemDofs(); //==================== const uint el_ngauss = ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussPointsNumber(); for (uint qp=0; qp< el_ngauss; qp++) { //======= "COMMON SHAPE PART"================== for (uint fe = 0; fe < QL; fe++) { currgp.SetPhiElDofsFEVB_g (fe,qp); currgp.SetDPhiDxezetaElDofsFEVB_g (fe,qp); } const double det = currgp.JacVectVV_g(xyz); const double dtxJxW_g = det*ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussWeight(qp); const double detb = det/el_ngauss; for (uint fe = 0; fe < QL; fe++) { currgp.SetDPhiDxyzElDofsFEVB_g (fe,qp); currgp.ExtendDphiDxyzElDofsFEVB_g(fe); } //======= end of the "COMMON SHAPE PART"================== Tempold.val_g(); for (uint i=0; i < Tempold._ndof/*the maximum number is for biquadratic*/; i++) { const double phii_g = currgp._phi_ndsQLVB_g[Tempold._FEord][i]; for (uint idim = 0; idim < space_dim; idim++) dphiidx_g[idim] = currgp._dphidxyz_ndsQLVB_g[Tempold._FEord][i+idim*Tempold._ndof]; //=========== FIRST ROW =============== currelem.Rhs()(i) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( 7.*phii_g ) + (1-currelem.GetBCDofFlag()[i])*detb*(Tempold._val_dofs[i]); currelem.Mat()(i,i) += (1-currelem.GetBCDofFlag()[i])*detb; // Matrix Assemblying --------------------------- for (uint j=0; j<Tempold._ndof; j++) { double phij_g = currgp._phi_ndsQLVB_g[Tempold._FEord][j]; for (uint idim = 0; idim < space_dim; idim++) { dphijdx_g [idim] = currgp._dphidxyz_ndsQLVB_g[Tempold._FEord][j+idim*Tempold._ndof]; } double Lap_g = Math::dot(dphijdx_g,dphiidx_g,space_dim); int ip1 = i + Tempold._ndof; int jp1 = j + Tempold._ndof; //============ FIRST ROW state delta T =============== //======= DIAGONAL ============================= currelem.Mat()(i,j) += currelem.GetBCDofFlag()[i]*dtxJxW_g*( Lap_g ); } //end j (col) } //end i (row) } // end of the quadrature point qp-loop currelem.Mat().print_scientific(std::cout); my_system._LinSolver[Level]->_KK->add_matrix(currelem.Mat(),currelem.GetDofIndices()); my_system._LinSolver[Level]->_RESC->add_vector(currelem.Rhs(),currelem.GetDofIndices()); } // end of element loop // ***************************************************************** delete [] dphijdx_g; delete [] dphiidx_g; }//END VOLUME my_system._LinSolver[Level]->_KK->close(); my_system._LinSolver[Level]->_RESC->close(); #ifdef DEFAULT_PRINT_INFO std::cout << " Matrix and RHS assembled for equation " << my_system.name() << " Level "<< Level << " dofs " << my_system._LinSolver[Level]->_KK->n() << std::endl; #endif return; }
//=================================================== /// This function assembles the matrix and the rhs: void GenMatRhsNS(MultiLevelProblem &ml_prob) { SystemTwo & my_system = ml_prob.get_system<SystemTwo>("Eqn_NS"); const unsigned Level = my_system.GetLevelToAssemble(); const uint _AdvPic_fl = 1; const uint _AdvNew_fl = 0; const uint _Stab_fl = 0; const double _Komp_fac = 0.; //========== GEOMETRIC ELEMENT ======== const uint space_dim = ml_prob._ml_msh->GetDimension(); //====== reference values ======================== //====== related to Quantities on which Operators act, and to the choice of the "LEADING" EQUATION Operator const double IRe = 1./ml_prob.GetInputParser().get("Re"); const double IFr = 1./ml_prob.GetInputParser().get("Fr"); //================================================ //================================================ //=======Operators @ gauss ======================= std::vector<double> dphijdx_g(space_dim); // ShapeDer(): used for Laplacian,Divergence, ..., associated to an Unknown Quantity std::vector<double> dphiidx_g(space_dim); // Test(): used for Laplacian,Advection,Divergence... associated to an Unknown Quantity std::vector<double> AdvRhs_g(space_dim); //Operator: Adv(u,u,phi) //================================================ my_system._LinSolver[Level]->_KK->zero(); my_system._LinSolver[Level]->_RESC->zero(); // ========================================== Mesh *mymsh = ml_prob._ml_msh->GetLevel(Level); elem *myel = mymsh->el; const unsigned myproc = mymsh->processor_id(); // ========================================== // ========================================== {//BEGIN VOLUME //======================== //======================== const uint mesh_vb = VV; const uint nel_e = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level+1]; const uint nel_b = ml_prob.GetMeshTwo()._off_el[mesh_vb][ml_prob.GetMeshTwo()._NoLevels*myproc+Level]; for (int iel=0; iel < (nel_e - nel_b); iel++) { CurrentElem<double> currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType(),mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQuadratureRule(currelem.GetDim())); //=========INTERNAL QUANTITIES (unknowns of the equation) ================== CurrentQuantity VelOldX(currgp); VelOldX._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Velocity0"); VelOldX._SolName = "Qty_Velocity0"; VelOldX.VectWithQtyFillBasic(); VelOldX.Allocate(); CurrentQuantity VelOldY(currgp); VelOldY._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Velocity1"); VelOldY._SolName = "Qty_Velocity1"; VelOldY.VectWithQtyFillBasic(); VelOldY.Allocate(); std::vector<CurrentQuantity*> VelOld_vec; VelOld_vec.push_back(&VelOldX); VelOld_vec.push_back(&VelOldY); const uint qtyzero_ord = VelOldX._FEord; const uint qtyzero_ndof = VelOldX._ndof; //same as Y //========= CurrentQuantity pressOld(currgp); pressOld._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_Pressure"); pressOld._SolName = "Qty_Pressure"; pressOld.VectWithQtyFillBasic(); pressOld.Allocate(); const uint qtyone_ord = pressOld._FEord; const uint qtyone_ndof = pressOld._ndof; //order const uint qtyZeroToOne_DofOffset = VelOldX._ndof + VelOldY._ndof;//VelOld._ndof*VelOld._dim; //========= END INTERNAL QUANTITIES (unknowns of the equation) ================= //=========EXTERNAL QUANTITIES (couplings) ===== //========= //DOMAIN MAPPING CurrentQuantity xyz(currgp); //domain xyz._dim = space_dim; xyz._FEord = MESH_MAPPING_FE; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); //other Physical constant Quantities //=======gravity================================== CurrentQuantity gravity(currgp); gravity._dim = space_dim; // gravity.Allocate(); CANNOT DO THIS NOW BECAUSE NOT ALL THE DATA FOR THE ALLOCATION ARE FILLED gravity._val_g.resize(gravity._dim); gravity._val_g[0] = ml_prob.GetInputParser().get("dirgx"); gravity._val_g[1] = ml_prob.GetInputParser().get("dirgy"); if ( space_dim == 3 ) gravity._val_g[2] = ml_prob.GetInputParser().get("dirgz"); //======================== //======================== currelem.Mat().zero(); currelem.Rhs().zero(); currelem.SetDofobjConnCoords(); currelem.SetElDofsBc(); currelem.ConvertElemCoordsToMappingOrd(xyz); //=======RETRIEVE the DOFS of the UNKNOWN QUANTITIES,i.e. MY EQUATION VelOldX.GetElemDofs(); VelOldY.GetElemDofs(); pressOld.GetElemDofs(); const uint el_ngauss = ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussPointsNumber(); for (uint qp = 0; qp < el_ngauss; qp++) { //=======here starts the "COMMON SHAPE PART"================== // the call of these things should be related to the Operator //also, the choice of the QuadratureRule should be dependent of the Involved Operators //and the FE orders on which these Operators act //these phi and dphi are used for the different stages: //BEFORE i: by the interpolation functions //INSIDE i: for the tEST functions and derivatives //INSIDE j: for the SHAPE functions and derivatives //again, it should be the Operator to decide what functions to be called, //for what FE ORDER and what DERIVATIVE ORDER //if we decide that the PREPARATION of the tEST and SHAPE //of a certain Unknown are COMMON TO ALL, //Then we must only concentrate on preparing the OTHER involved quantities in that Operator for (uint fe = 0; fe < QL; fe++) { currgp.SetPhiElDofsFEVB_g (fe,qp); currgp.SetDPhiDxezetaElDofsFEVB_g (fe,qp); } const double det = currgp.JacVectVV_g(xyz); const double dtxJxW_g = det*ml_prob.GetQuadratureRule(currelem.GetDim()).GetGaussWeight(qp); const double detb = det/el_ngauss; for (uint fe = 0; fe < QL; fe++) { currgp.SetDPhiDxyzElDofsFEVB_g (fe,qp); currgp.ExtendDphiDxyzElDofsFEVB_g(fe); } //=======end of the "COMMON SHAPE PART"================== //now we want to fill the element matrix and rhs with ONLY values AT GAUSS POINTS //we can divide the values at Gauss points into three parts: //1-constant values //2-values which depend on (i) //3-values which depend on (i,j) //1- can be used for filling both Ke and Fe //2- can be used to fill Fe and also Ke //3- can be used only for filling Ke //Here, before entering the (i,j) loop, you compute quantities that DO NOT depend on (i,j), //therefore the ELEMENT SUM, GAUSS SUM And tEST/SHAPE sums have ALL been performed //but, these quantities depend on idim and jdim, because they are involved in multiplications with tEST and SHAPE functions //Internal Quantities VelOldX.val_g(); VelOldX.grad_g(); VelOldY.val_g(); VelOldY.grad_g(); //Advection all VelOld for (uint idim=0; idim<space_dim; idim++) { AdvRhs_g[idim]=0.;} for (uint idim=0; idim<space_dim; idim++) { for (uint b=0; b<space_dim; b++) { AdvRhs_g[idim] += VelOld_vec[b]->_val_g[0]*VelOld_vec[idim]->_grad_g[0][b]; } } // grad is [ivar][idim], i.e. [u v w][x y z] //Divergence VelOld double Div_g=0.; for (uint idim=0; idim<space_dim; idim++) Div_g += VelOld_vec[idim]->_grad_g[0][idim]; //============================================================== //========= FILLING ELEMENT MAT/RHS (i loop) ==================== //============================================================== // TODO according to the order we should switch DIM loop and DOF loop for (uint i=0; i<qtyzero_ndof; i++) { //======="COMMON tEST PART for QTYZERO": func and derivative, of the QTYZERO FE ORD ========== const double phii_g = currgp._phi_ndsQLVB_g[qtyzero_ord][i]; for (uint idim=0; idim<space_dim; idim++) dphiidx_g[idim] = currgp._dphidxyz_ndsQLVB_g[qtyzero_ord][i+idim*qtyzero_ndof]; //======= END "COMMON tEST PART for QTYZERO" ========== for (uint idim=0; idim<space_dim; idim++) { const uint irowq=i+idim*qtyzero_ndof; // (i): dof of the tEST function //(idim): component of the tEST function currelem.Rhs()(irowq) += currelem.GetBCDofFlag()[irowq]* dtxJxW_g*( + _AdvNew_fl* AdvRhs_g[idim]*phii_g // NONLIN + IFr*gravity._val_g[idim]*phii_g // gravity ) + (1-currelem.GetBCDofFlag()[irowq])*detb*VelOld_vec[idim]->_val_dofs[i] //Dirichlet bc ; } // end filling element rhs u for (uint idim=0; idim<space_dim; idim++) { // filling diagonal for Dirichlet bc const uint irowq = i+idim*qtyzero_ndof; currelem.Mat()(irowq,irowq) += (1-currelem.GetBCDofFlag()[irowq])*detb; } // end filling diagonal for Dirichlet bc //============ QTYZERO x QTYZERO dofs matrix (A matrix) ============ for (uint j=0; j< qtyzero_ndof; j++) { //======="COMMON SHAPE PART for QTYZERO": func and derivative, of the QTYZERO FE ORD ========== // (j): dof of the SHAPE function double phij_g = currgp._phi_ndsQLVB_g[qtyzero_ord][j]; for (uint idim=0; idim<space_dim; idim++) dphijdx_g[idim] = currgp._dphidxyz_ndsQLVB_g[qtyzero_ord][j+idim*qtyzero_ndof]; //======= END "COMMON SHAPE PART for QTYZERO" ========== double Lap_g = Math::dot(&dphijdx_g[0],&dphiidx_g[0],space_dim); double Adv_g=0.; for (uint idim=0; idim<space_dim; idim++) Adv_g += VelOld_vec[idim]->_val_g[0] * dphijdx_g[idim]; // =Math::dot(&VelOld._val_g[0],dphijdx_g,space_dim); for (uint idim=0; idim<space_dim; idim++) { //filled in as 1-2-3 // 4-5-6 // 7-8-9 int irowq = i+idim*qtyzero_ndof; //(i) is still the dof of the tEST functions //(idim): component of the tEST functions currelem.Mat()(irowq,j+idim*qtyzero_ndof) // diagonal blocks [1-5-9] [idim(rows),idim(columns)] //(idim): component of the SHAPE functions += currelem.GetBCDofFlag()[irowq]* dtxJxW_g*( + _AdvPic_fl* Adv_g*phii_g //TODO NONLIN + _AdvNew_fl*phij_g*VelOld_vec[idim]->_grad_g[0][idim]*phii_g //TODO NONLIN + _AdvPic_fl*_Stab_fl* 0.5*Div_g*phij_g*phii_g //TODO NONLIN + IRe*( dphijdx_g[idim]*dphiidx_g[idim] + Lap_g) ); int idimp1=(idim+1)%space_dim; // block +1 [2-6-7] [idim(rows),idim+1(columns)] //(idimp1): component of the SHAPE functions currelem.Mat()(irowq,j+idimp1*qtyzero_ndof) += currelem.GetBCDofFlag()[irowq]* dtxJxW_g*( _AdvNew_fl*phij_g*VelOld_vec[idim]->_grad_g[0][idimp1]*phii_g //TODO NONLIN + IRe*( dphijdx_g[idim]*dphiidx_g[idimp1]) ); } } //============ END QTYZERO x QTYZERO dofs matrix (A matrix) ============ //============ QTYZERO x QTYONE dofs matrix (B^T matrix) // ( p*div(v) ) (NS eq) ============ for (uint j=0; j<qtyone_ndof; j++) { //======="COMMON SHAPE PART for QTYONE" ================== const double psij_g = currgp._phi_ndsQLVB_g[qtyone_ord][j]; //======="COMMON SHAPE PART for QTYONE" - END ============ const int jclml = j + qtyZeroToOne_DofOffset; for (uint idim=0; idim<space_dim; idim++) { uint irowq = i+idim*qtyzero_ndof; currelem.Mat()(irowq,jclml) += currelem.GetBCDofFlag()[irowq]* dtxJxW_g*(-psij_g*dphiidx_g[idim]); /** (-1.)*/ } } //============ END QTYZERO x QTYONE dofs matrix (B^T matrix) ============ if (i < qtyone_ndof) { //======="COMMON tEST PART for QTYONE" ============ double psii_g = currgp._phi_ndsQLVB_g[qtyone_ord][i]; //======= "COMMON tEST PART for QTYONE" - END ============ const uint irowl = i + qtyZeroToOne_DofOffset; currelem.Rhs()(irowl)=0.; // rhs // Mat()(irowl,j+space_dim*qtyzero_ndof) += (1./dt)*dtxJxW_g*(psii_g*psij_g)*_Komp_fac/dt; //no bc here (KOMP dp/dt=rho*div) for (uint j=0; j<qtyzero_ndof; j++) { // B element matrix q*div(u) //======="COMMON SHAPE PART for QTYZERO" ================== for (uint idim=0; idim<space_dim; idim++) dphijdx_g[idim] = currgp._dphidxyz_ndsQLVB_g[qtyzero_ord][j+idim*qtyzero_ndof]; //======="COMMON SHAPE PART for QTYZERO" - END ============ for (uint idim=0; idim<space_dim; idim++) currelem.Mat()(irowl,j+idim*qtyzero_ndof) += -/*(1./dt)**/dtxJxW_g*psii_g*dphijdx_g[idim]; } } // end pressure eq (cont) } //=================================================================== //========= END FILLING ELEMENT MAT/RHS (i loop) ===================== //=================================================================== } //============================================================== //================== END GAUSS LOOP (qp loop) ====================== //============================================================== /// Add element matrix and rhs to the global ones. my_system._LinSolver[Level]->_KK->add_matrix(currelem.Mat(),currelem.GetDofIndices()); my_system._LinSolver[Level]->_RESC->add_vector(currelem.Rhs(),currelem.GetDofIndices()); } // end of element loop }//END VOLUME my_system._LinSolver[Level]->_KK->close(); my_system._LinSolver[Level]->_RESC->close(); #ifdef DEFAULT_PRINT_INFO std::cout << " GenMatRhs " << my_system.name() << ": assembled Level " << Level << " with " << my_system._LinSolver[Level]->_KK->m() << " dofs" << std::endl; #endif return; }