From f9a9b71fc75682752527c3d4b111782b95f8a20c Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Mon, 9 Mar 2015 22:26:46 -0500 Subject: [PATCH 01/20] Adding Solutions to the MLProblem does not hurt --- applications/OptimalControl/tempopt/main.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/applications/OptimalControl/tempopt/main.cpp b/applications/OptimalControl/tempopt/main.cpp index a5a70ccc4..2bd954791 100644 --- a/applications/OptimalControl/tempopt/main.cpp +++ b/applications/OptimalControl/tempopt/main.cpp @@ -135,8 +135,13 @@ void GenMatRhsNS(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr ml_msh.SetDomain(&mybox); MultiLevelSolution ml_sol(&ml_msh); - ml_sol.AddSolution("FAKE",LAGRANGE,SECOND,0); - + ml_sol.AddSolution("Qty_Temperature",LAGRANGE,SECOND,0); + ml_sol.AddSolution("Qty_TempLift",LAGRANGE,SECOND,0); + ml_sol.AddSolution("Qty_TempAdj",LAGRANGE,SECOND,0); + ml_sol.AddSolution("Qty_Velocity",LAGRANGE,SECOND,0); + ml_sol.AddSolution("Qty_Pressure",LAGRANGE,FIRST,0); + ml_sol.AddSolution("Qty_TempDes",LAGRANGE,SECOND,0);//this is not going to be an Unknown! + MultiLevelProblem ml_prob(&ml_sol); ml_prob.SetMeshTwo(&mesh); ml_prob.SetQruleAndElemType("fifth"); From 4ac12de13b069c6fe73d0a4413bb20ac8779501d Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Mon, 9 Mar 2015 23:19:08 -0500 Subject: [PATCH 02/20] AddSolutionVector --- applications/OptimalControl/tempopt/main.cpp | 11 ++++++++--- src/solution/MultiLevelSolution.cpp | 14 +++++++++++++- src/solution/MultiLevelSolution.hpp | 3 +++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/applications/OptimalControl/tempopt/main.cpp b/applications/OptimalControl/tempopt/main.cpp index 2bd954791..c03d177de 100644 --- a/applications/OptimalControl/tempopt/main.cpp +++ b/applications/OptimalControl/tempopt/main.cpp @@ -138,10 +138,15 @@ void GenMatRhsNS(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr ml_sol.AddSolution("Qty_Temperature",LAGRANGE,SECOND,0); ml_sol.AddSolution("Qty_TempLift",LAGRANGE,SECOND,0); ml_sol.AddSolution("Qty_TempAdj",LAGRANGE,SECOND,0); - ml_sol.AddSolution("Qty_Velocity",LAGRANGE,SECOND,0); + ml_sol.AddSolutionVector(ml_msh.GetDimension(),"Qty_Velocity",LAGRANGE,SECOND,0); ml_sol.AddSolution("Qty_Pressure",LAGRANGE,FIRST,0); ml_sol.AddSolution("Qty_TempDes",LAGRANGE,SECOND,0);//this is not going to be an Unknown! + ml_sol.Initialize("All"); /// @todo you have to call this before you can print @todo I can also call it after instantiation MLProblem + ml_sol.SetWriter(VTK); + std::vector print_vars(1); print_vars[0] = "All"; // we should find a way to make this easier + ml_sol.GetWriter()->write(files.GetOutputPath(),"biquadratic",print_vars); + MultiLevelProblem ml_prob(&ml_sol); ml_prob.SetMeshTwo(&mesh); ml_prob.SetQruleAndElemType("fifth"); @@ -155,13 +160,13 @@ void GenMatRhsNS(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr // not all the Quantities need to be unknowns of an equation SystemTwo & eqnNS = ml_prob.add_system("Eqn_NS"); - eqnNS.AddSolutionToSystemPDE("FAKE"); +// eqnNS.AddSolutionToSystemPDE("FAKE"); //do the vector version of it eqnNS.AddUnknownToSystemPDE(&velocity); eqnNS.AddUnknownToSystemPDE(&pressure); eqnNS.SetAssembleFunction(GenMatRhsNS); SystemTwo & eqnT = ml_prob.add_system("Eqn_T"); - eqnT.AddSolutionToSystemPDE("FAKE"); +// eqnT.AddSolutionToSystemPDE("FAKE"); eqnT.AddUnknownToSystemPDE(&temperature); eqnT.AddUnknownToSystemPDE(&templift); eqnT.AddUnknownToSystemPDE(&tempadj);//the order in which you add defines the order in the matrix as well, so it is in tune with the assemble function diff --git a/src/solution/MultiLevelSolution.cpp b/src/solution/MultiLevelSolution.cpp index e5e52b5b9..64f396485 100644 --- a/src/solution/MultiLevelSolution.cpp +++ b/src/solution/MultiLevelSolution.cpp @@ -131,6 +131,18 @@ void MultiLevelSolution::AddSolution(const char name[], const FEFamily fefamily, } } + void MultiLevelSolution::AddSolutionVector(const unsigned n_components, const std::string name, const FEFamily fefamily, const FEOrder order, unsigned tmorder, const bool &Pde_type) { + + for (unsigned i=0; i Date: Tue, 10 Mar 2015 11:49:38 -0500 Subject: [PATCH 03/20] Passed iel to CurrentElem constructor --- applications/OptimalControl/fe_test/EqnT.cpp | 2 +- applications/OptimalControl/mhdopt/EqnMHD.cpp | 4 +- .../OptimalControl/mhdopt/EqnMHDAD.cpp | 4 +- .../OptimalControl/mhdopt/EqnMHDCONT.cpp | 4 +- applications/OptimalControl/mhdopt/EqnNS.cpp | 4 +- .../OptimalControl/mhdopt/EqnNSAD.cpp | 4 +- .../OptimalControl/mhdopt/OptLoop.cpp | 29 +++++----- .../OptimalControl/mhdopt/OptQuantities.cpp | 26 --------- .../OptimalControl/mhdopt/OptQuantities.hpp | 9 ---- applications/OptimalControl/tempopt/EqnNS.cpp | 4 +- applications/OptimalControl/tempopt/EqnT.cpp | 5 +- .../OptimalControl/tempopt/OptLoop.cpp | 53 ++++++++++--------- .../OptimalControl/tempopt/TempQuantities.cpp | 28 ---------- .../OptimalControl/tempopt/TempQuantities.hpp | 7 --- applications/OptimalControl/tempopt/main.cpp | 2 +- src/equations/BoundaryConditions.cpp | 5 +- src/equations/CurrentElem.cpp | 5 +- src/equations/CurrentElem.hpp | 4 +- src/equations/CurrentQuantity.cpp | 19 +++++++ src/equations/SystemTwo.cpp | 7 +-- src/utils/Math.hpp | 31 +++++------ 21 files changed, 108 insertions(+), 148 deletions(-) diff --git a/applications/OptimalControl/fe_test/EqnT.cpp b/applications/OptimalControl/fe_test/EqnT.cpp index 3522d6282..4b2d41cb7 100644 --- a/applications/OptimalControl/fe_test/EqnT.cpp +++ b/applications/OptimalControl/fe_test/EqnT.cpp @@ -65,7 +65,7 @@ for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/EqnMHD.cpp b/applications/OptimalControl/mhdopt/EqnMHD.cpp index c6f85721a..f36799133 100644 --- a/applications/OptimalControl/mhdopt/EqnMHD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHD.cpp @@ -71,7 +71,7 @@ void GenMatRhsMHD(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -359,7 +359,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp index 308837d42..adc85e315 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp @@ -67,7 +67,7 @@ const int NonStatMHDAD = (int) ml_prob.GetInputParser().get("NonStatMHDAD"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -321,7 +321,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp index 3493736eb..74a168f7a 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp @@ -77,7 +77,7 @@ using namespace femus; for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -373,7 +373,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/EqnNS.cpp b/applications/OptimalControl/mhdopt/EqnNS.cpp index 8cf5db62b..23150e6db 100644 --- a/applications/OptimalControl/mhdopt/EqnNS.cpp +++ b/applications/OptimalControl/mhdopt/EqnNS.cpp @@ -159,7 +159,7 @@ const int NonStatNS = (int) ml_prob.GetInputParser().get("NonStatNS"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -547,7 +547,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0; iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/EqnNSAD.cpp b/applications/OptimalControl/mhdopt/EqnNSAD.cpp index 3dbc7dd2d..bdddffcdc 100644 --- a/applications/OptimalControl/mhdopt/EqnNSAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnNSAD.cpp @@ -66,7 +66,7 @@ const int NonStatNSAD = (int) ml_prob.GetInputParser().get("NonStatNSAD"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -327,7 +327,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/mhdopt/OptLoop.cpp b/applications/OptimalControl/mhdopt/OptLoop.cpp index 0e49ee6ab..fa6a2fc8c 100644 --- a/applications/OptimalControl/mhdopt/OptLoop.cpp +++ b/applications/OptimalControl/mhdopt/OptLoop.cpp @@ -511,15 +511,25 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint mesh_vb = VV; Mesh *mymsh = eqn->GetMLProb()._ml_msh->GetLevel(Level); - CurrentElem currelem(Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); - currelem.SetMesh(mymsh); - CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); - // processor index const uint myproc = mesh->_iproc; // geometry ----- const uint space_dim = mesh->get_dim(); + + + double integral=0.; + + +//parallel sum + const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; + const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; + + for (uint iel=0; iel < (nel_e - nel_b); iel++) { + + CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + currelem.SetMesh(mymsh); + CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); //========= DOMAIN MAPPING CurrentQuantity xyz(currgp); @@ -546,17 +556,10 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S VelDes._qtyptr = eqn->GetMLProb().GetQtyMap().GetQuantity("Qty_DesVelocity"); VelDes.VectWithQtyFillBasic(); VelDes.Allocate(); - - double integral=0.; const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - -//parallel sum - const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; - const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; - - for (uint iel=0; iel < (nel_e - nel_b); iel++) { - + + currelem.SetDofobjConnCoords(mesh->_iproc,iel); currelem.SetMidpoint(); diff --git a/applications/OptimalControl/mhdopt/OptQuantities.cpp b/applications/OptimalControl/mhdopt/OptQuantities.cpp index fc6d81aa9..d3456e826 100644 --- a/applications/OptimalControl/mhdopt/OptQuantities.cpp +++ b/applications/OptimalControl/mhdopt/OptQuantities.cpp @@ -219,32 +219,6 @@ void Velocity::Function_txyz(const double t,const double* xp, double* func) cons } -//============================================================= -void Velocity::strain_txyz(const double t, const double* xyz,double strain[][DIMENSION]) const { - -//here, tau is a tensor, so tau dot n is a vector which in general has a NORMAL and a TANGENTIAL component - - const double Lref = _qtymap.GetInputParser()->get("Lref"); - double ILref = 1./Lref; - const double lye = _qtymap.GetMeshTwo()->GetDomain()->_domain_rtmap.get("lye"); - const double x=xyz[0]; - const double y=xyz[1]; -#if DIMENSION==3 - const double z=xyz[2]; -#endif - - - strain[0][0] = 0.; //ux,x - strain[0][1] = strain[1][0] = 0. ;//0.5*(uy,x+ux,y) - strain[1][1] = 0.*(-(lye*ILref-y)); //uy,y -#if (DIMENSION==3) - strain[0][2] = strain[2][0] = 0. ; //0.5*(uz,x+ux,z) - strain[1][2] = strain[2][1] = 0. ; //0.5*(uy,z+uz,y) - strain[2][2] = 0. ; //uz,z -#endif - -return; -} //============================================================= diff --git a/applications/OptimalControl/mhdopt/OptQuantities.hpp b/applications/OptimalControl/mhdopt/OptQuantities.hpp index 2d0a293ec..894369880 100644 --- a/applications/OptimalControl/mhdopt/OptQuantities.hpp +++ b/applications/OptimalControl/mhdopt/OptQuantities.hpp @@ -141,15 +141,6 @@ class Velocity : public Quantity { void bc_flag_txyz(const double t, const double* xp, std::vector & flag) const; void initialize_xyz(const double* xp, std::vector & value) const; - //specific function - //this is the STRAIN DERIVATIVE of VELOCITY, so it must stay here - //from the physical and also mathematical point of view - //the shape funcs of the same order as v will then be used and so on -//multi-dimensional arrays must have bounds for all dimensions except the first - void strain_txyz(const double t, const double* xp,double strain[][DIMENSION]) const; //TODO remove this DIMENSION and use double pointers or std vector - - - }; class VelocityAdj : public Quantity { diff --git a/applications/OptimalControl/tempopt/EqnNS.cpp b/applications/OptimalControl/tempopt/EqnNS.cpp index 807bbc29d..caae14939 100644 --- a/applications/OptimalControl/tempopt/EqnNS.cpp +++ b/applications/OptimalControl/tempopt/EqnNS.cpp @@ -83,7 +83,7 @@ for (int iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -378,7 +378,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0; iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/tempopt/EqnT.cpp b/applications/OptimalControl/tempopt/EqnT.cpp index 643b0b4b0..7210a0189 100644 --- a/applications/OptimalControl/tempopt/EqnT.cpp +++ b/applications/OptimalControl/tempopt/EqnT.cpp @@ -29,7 +29,6 @@ // application #include "TempQuantities.hpp" -#include "../../../src/equations/CurrentElem.hpp" // The question is: WHERE is the ORDER of the VARIABLES established? @@ -122,7 +121,7 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -412,7 +411,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); diff --git a/applications/OptimalControl/tempopt/OptLoop.cpp b/applications/OptimalControl/tempopt/OptLoop.cpp index 76e8d41a1..864f9efe2 100644 --- a/applications/OptimalControl/tempopt/OptLoop.cpp +++ b/applications/OptimalControl/tempopt/OptLoop.cpp @@ -89,7 +89,19 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint mesh_vb = VV; - CurrentElem currelem(Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + + + + double integral = 0.; + + +//parallel sum + const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; + const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; + + for (uint iel=0; iel < (nel_e - nel_b); iel++) { + + CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); @@ -124,18 +136,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S xyz_refbox._FEord = MESH_ORDER; xyz_refbox._ndof = mymsh->el->GetElementDofNumber(ZERO_ELEM,BIQUADR_FE); xyz_refbox.Allocate(); - - - double integral = 0.; - - const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - -//parallel sum - const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; - const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; - for (uint iel=0; iel < (nel_e - nel_b); iel++) { - currelem.SetDofobjConnCoords(myproc,iel); currelem.SetMidpoint(); @@ -154,7 +155,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S if ( Tdes._eqnptr != NULL ) Tdes.GetElemDofs(); else Tdes._qtyptr->FunctionDof(Tdes,0.,&xyz_refbox._val_dofs[0]); - + const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); for (uint qp = 0; qp < el_ngauss; qp++) { @@ -228,7 +229,18 @@ double ComputeNormControl (const uint Level, const MultiLevelMeshTwo* mesh, cons Mesh *mymsh = eqn->GetMLProb()._ml_msh->GetLevel(Level); - CurrentElem currelem(Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + + + double integral = 0.; + + +//parallel sum + const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; + const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; + + for (int iel=0; iel < (nel_e - nel_b); iel++) { + + CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); @@ -254,18 +266,9 @@ double ComputeNormControl (const uint Level, const MultiLevelMeshTwo* mesh, cons xyz_refbox._ndof = mymsh->el->GetElementDofNumber(ZERO_ELEM,BIQUADR_FE); xyz_refbox.Allocate(); - - double integral = 0.; - //loop over the geom el types - const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - -//parallel sum - const uint nel_e = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level+1]; - const uint nel_b = mesh->_off_el[mesh_vb][mesh->_NoLevels*myproc+Level]; - - for (int iel=0; iel < (nel_e - nel_b); iel++) { - + const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); + currelem.SetDofobjConnCoords(myproc,iel); currelem.SetMidpoint(); diff --git a/applications/OptimalControl/tempopt/TempQuantities.cpp b/applications/OptimalControl/tempopt/TempQuantities.cpp index 7b88164c5..de46a999e 100644 --- a/applications/OptimalControl/tempopt/TempQuantities.cpp +++ b/applications/OptimalControl/tempopt/TempQuantities.cpp @@ -112,34 +112,6 @@ void Velocity::Function_txyz(const double /*t*/,const double* xp, double* func) } - -//============================================================= -void Velocity::strain_txyz(const double /*t*/, const double* xyz,double strain[][DIMENSION]) const { - -//here, tau is a tensor, so tau dot n is a vector which in general has a NORMAL and a TANGENTIAL component - - const double Lref = _qtymap.GetInputParser()->get("Lref"); - double ILref = 1./Lref; - const double lye = _qtymap.GetMeshTwo()->GetDomain()->_domain_rtmap.get("lye"); -// const double x=xyz[0]; - const double y=xyz[1]; - if (_qtymap.GetMeshTwo()->get_dim() == 3) { - const double z=xyz[2]; - } - - strain[0][0] = 0.; //ux,x - strain[0][1] = strain[1][0] = 0. ;//0.5*(uy,x+ux,y) - strain[1][1] = 0.*(-(lye*ILref-y)); //uy,y - if (_qtymap.GetMeshTwo()->get_dim() == 3) { - strain[0][2] = strain[2][0] = 0. ; //0.5*(uz,x+ux,z) - strain[1][2] = strain[2][1] = 0. ; //0.5*(uy,z+uz,y) - strain[2][2] = 0. ; //uz,z - } - -return; -} - - //============================================================= /// prescribed pressure at the boundary //no initial condition for pressure is required, because it has no time derivative diff --git a/applications/OptimalControl/tempopt/TempQuantities.hpp b/applications/OptimalControl/tempopt/TempQuantities.hpp index 66ce30698..ba8d3e370 100644 --- a/applications/OptimalControl/tempopt/TempQuantities.hpp +++ b/applications/OptimalControl/tempopt/TempQuantities.hpp @@ -98,13 +98,6 @@ class Velocity : public Quantity { void bc_flag_txyz(const double t, const double* xp, std::vector & flag) const; void initialize_xyz(const double* xp, std::vector & value) const; - //specific function - //this is the STRAIN DERIVATIVE of VELOCITY, so it must stay here - //from the physical and also mathematical point of view - //the shape funcs of the same order as v will then be used and so on -//multi-dimensional arrays must have bounds for all dimensions except the first - void strain_txyz(const double t, const double* xp,double strain[][DIMENSION]) const; //TODO convert this double array - }; diff --git a/applications/OptimalControl/tempopt/main.cpp b/applications/OptimalControl/tempopt/main.cpp index c03d177de..ec366715a 100644 --- a/applications/OptimalControl/tempopt/main.cpp +++ b/applications/OptimalControl/tempopt/main.cpp @@ -140,7 +140,7 @@ void GenMatRhsNS(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr ml_sol.AddSolution("Qty_TempAdj",LAGRANGE,SECOND,0); ml_sol.AddSolutionVector(ml_msh.GetDimension(),"Qty_Velocity",LAGRANGE,SECOND,0); ml_sol.AddSolution("Qty_Pressure",LAGRANGE,FIRST,0); - ml_sol.AddSolution("Qty_TempDes",LAGRANGE,SECOND,0);//this is not going to be an Unknown! + ml_sol.AddSolution("Qty_TempDes",LAGRANGE,SECOND,0,false); //this is not going to be an Unknown! ml_sol.Initialize("All"); /// @todo you have to call this before you can print @todo I can also call it after instantiation MLProblem ml_sol.SetWriter(VTK); diff --git a/src/equations/BoundaryConditions.cpp b/src/equations/BoundaryConditions.cpp index 1d120fb15..300b416d8 100644 --- a/src/equations/BoundaryConditions.cpp +++ b/src/equations/BoundaryConditions.cpp @@ -223,14 +223,15 @@ void BoundaryConditions::GenerateBdc() { for (uint Level=0; Level <_dofmap->_mesh._NoLevels;Level++) { //loop over the levels Mesh *mymsh = _dofmap->_eqn->GetMLProb()._ml_msh->GetLevel(Level); - CurrentElem currelem(Level,BB,_dofmap->_eqn,_dofmap->_mesh,_dofmap->_eqn->GetMLProb().GetElemType()); - currelem.SetMesh(mymsh); const uint el_nnodes_b = mymsh->el->GetElementFaceDofNumber(ZERO_ELEM,ZERO_FACE,BIQUADR_FE); for (uint isubd=0; isubd<_dofmap->_mesh._NoSubdom; ++isubd) { uint iel_b = _dofmap->_mesh._off_el[BB][ _dofmap->_mesh._NoLevels*isubd + Level]; uint iel_e = _dofmap->_mesh._off_el[BB][ _dofmap->_mesh._NoLevels*isubd + Level+1]; for (uint iel=0; iel < (iel_e - iel_b); iel++) { + + CurrentElem currelem(iel,Level,BB,_dofmap->_eqn,_dofmap->_mesh,_dofmap->_eqn->GetMLProb().GetElemType()); + currelem.SetMesh(mymsh); currelem.SetDofobjConnCoords(isubd,iel); currelem.SetMidpoint(); diff --git a/src/equations/CurrentElem.cpp b/src/equations/CurrentElem.cpp index 0ce609e57..b0904029b 100644 --- a/src/equations/CurrentElem.cpp +++ b/src/equations/CurrentElem.cpp @@ -27,13 +27,14 @@ namespace femus { - CurrentElem::CurrentElem(const uint level, const uint vb, const SystemTwo * eqn_in, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type_in ): + CurrentElem::CurrentElem(const uint iel_in, const uint level, const uint vb, const SystemTwo * eqn_in, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type_in ): _eqn(eqn_in), _mesh(mesh), _dim(_mesh.get_dim()-vb), _elem_type(elem_type_in[mesh.get_dim()-vb -1]), _mesh_vb(vb), - _Level(level) + _Level(level), + _iel(iel_in) { //========== Current "Geometric Element" ======================== diff --git a/src/equations/CurrentElem.hpp b/src/equations/CurrentElem.hpp index 5da41c98b..11e70ae4a 100644 --- a/src/equations/CurrentElem.hpp +++ b/src/equations/CurrentElem.hpp @@ -36,7 +36,7 @@ class CurrentQuantity; public: - CurrentElem(const uint level, const uint vb, const SystemTwo*, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type); + CurrentElem(const uint iel_in, const uint level, const uint vb, const SystemTwo*, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type); inline const uint GetVb() const { return _mesh.get_dim() - _dim; @@ -134,6 +134,8 @@ class CurrentQuantity; const uint _mesh_vb; //index for the mesh const uint _Level; //the level to which the element belongs + + const uint _iel; //the index of the element (input for the parallel partition) }; diff --git a/src/equations/CurrentQuantity.cpp b/src/equations/CurrentQuantity.cpp index 384fc5e9b..13e91448c 100644 --- a/src/equations/CurrentQuantity.cpp +++ b/src/equations/CurrentQuantity.cpp @@ -290,6 +290,25 @@ void CurrentQuantity::GetElemDofs() { } +// void CurrentQuantity::GetElemDofs_two() { +// +// unsigned SolType2 = ml_sol->GetSolutionType(ml_sol->GetIndex(_qtyptr->_name)); +// unsigned nve2 = _currEl._mesh_new->el->GetElementDofNumber(kel,SolType2); +// +// +// for (unsigned i=0;iel->GetMeshDof(kel,i,SolType2); +// unsigned inode_Metis=_currEl._mesh_new->GetMetisDof(inode,SolType2); +// for(int j=0; j<_currEl._mesh_new->GetDimension(); j++) { +// // velocity dofs +// Soli[indexVAR[j]][i] = (*mysolution->_Sol[indVAR[j]])(inode_Metis); +// // dofsVAR[j][i] = myLinEqSolver->GetKKDof(indVAR[j],indexVAR[j],inode); +// } +// } + + + + // clearly _el_average must be allocated already!!! void CurrentQuantity::SetElemAverage() { diff --git a/src/equations/SystemTwo.cpp b/src/equations/SystemTwo.cpp index 2e452fe47..133fe9d8c 100644 --- a/src/equations/SystemTwo.cpp +++ b/src/equations/SystemTwo.cpp @@ -230,15 +230,16 @@ void SystemTwo::Initialize() { for (uint Level = 0; Level< GetGridn(); Level++) { Mesh *mymsh = GetMLProb()._ml_msh->GetLevel(Level); - CurrentElem currelem(Level,VV,this,GetMLProb().GetMeshTwo(),GetMLProb().GetElemType()); - currelem.SetMesh(mymsh); - const uint el_dof_objs = NVE[ GetMLProb().GetMeshTwo()._geomelem_flag[currelem.GetDim()-1] ][BIQUADR_FE]; uint iel_b = GetMLProb().GetMeshTwo()._off_el[VV][ GetMLProb().GetMeshTwo()._iproc*GetGridn() + Level ]; uint iel_e = GetMLProb().GetMeshTwo()._off_el[VV][ GetMLProb().GetMeshTwo()._iproc*GetGridn() + Level + 1]; for (uint iel=0; iel < (iel_e - iel_b); iel++) { + CurrentElem currelem(iel,Level,VV,this,GetMLProb().GetMeshTwo(),GetMLProb().GetElemType()); + currelem.SetMesh(mymsh); + const uint el_dof_objs = NVE[ GetMLProb().GetMeshTwo()._geomelem_flag[currelem.GetDim()-1] ][BIQUADR_FE]; + currelem.SetDofobjConnCoords(GetMLProb().GetMeshTwo()._iproc,iel); currelem.SetMidpoint(); diff --git a/src/utils/Math.hpp b/src/utils/Math.hpp index 43d7f1f88..9dd7b2fa1 100644 --- a/src/utils/Math.hpp +++ b/src/utils/Math.hpp @@ -107,10 +107,22 @@ const uint myproc = ml_prob.GetMeshTwo()._iproc; Mesh *mymsh = ml_prob._ml_msh->GetLevel(Level); - CurrentElem currelem(Level,vb,NULL,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); //element without equation + + 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,Level,vb,NULL,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); //element without equation currelem.SetMesh(mymsh); 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(); @@ -118,17 +130,6 @@ const uint myproc = ml_prob.GetMeshTwo()._iproc; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); - double integral = 0.; - -//loop over the geom el types - const uint el_ngauss = ml_prob.GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - -//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++) { - currelem.SetDofobjConnCoords(myproc,iel); currelem.SetMidpoint(); @@ -160,9 +161,9 @@ double myval_g = pt2func(time,xyz._val_g); 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 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 From f64792351f030719658ed0e0c5eb33b28ec1d689 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 12:41:17 -0500 Subject: [PATCH 04/20] Removed iel in SetDofobj function --- applications/OptimalControl/fe_test/EqnT.cpp | 2 +- applications/OptimalControl/mhdopt/EqnMHD.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnMHDAD.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnMHDCONT.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnNS.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnNSAD.cpp | 4 ++-- applications/OptimalControl/mhdopt/OptLoop.cpp | 2 +- applications/OptimalControl/tempopt/EqnNS.cpp | 4 ++-- applications/OptimalControl/tempopt/EqnT.cpp | 4 ++-- applications/OptimalControl/tempopt/OptLoop.cpp | 4 ++-- src/equations/BoundaryConditions.cpp | 2 +- src/equations/CurrentElem.cpp | 6 +++--- src/equations/CurrentElem.hpp | 2 +- src/equations/SystemTwo.cpp | 2 +- src/utils/Math.hpp | 2 +- 15 files changed, 25 insertions(+), 25 deletions(-) diff --git a/applications/OptimalControl/fe_test/EqnT.cpp b/applications/OptimalControl/fe_test/EqnT.cpp index 4b2d41cb7..16c05278e 100644 --- a/applications/OptimalControl/fe_test/EqnT.cpp +++ b/applications/OptimalControl/fe_test/EqnT.cpp @@ -106,7 +106,7 @@ currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHD.cpp b/applications/OptimalControl/mhdopt/EqnMHD.cpp index f36799133..0f752a5f6 100644 --- a/applications/OptimalControl/mhdopt/EqnMHD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHD.cpp @@ -155,7 +155,7 @@ void GenMatRhsMHD(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -449,7 +449,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc,iel); + currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp index adc85e315..3c27fd371 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp @@ -140,7 +140,7 @@ const int NonStatMHDAD = (int) ml_prob.GetInputParser().get("NonStatMHDAD"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc,iel); + currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -364,7 +364,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc,iel); + currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp index 74a168f7a..237656098 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp @@ -138,7 +138,7 @@ using namespace femus; currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc,iel); + currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -410,7 +410,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc,iel); + currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnNS.cpp b/applications/OptimalControl/mhdopt/EqnNS.cpp index 23150e6db..03995deaf 100644 --- a/applications/OptimalControl/mhdopt/EqnNS.cpp +++ b/applications/OptimalControl/mhdopt/EqnNS.cpp @@ -250,7 +250,7 @@ const int NonStatNS = (int) ml_prob.GetInputParser().get("NonStatNS"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -601,7 +601,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnNSAD.cpp b/applications/OptimalControl/mhdopt/EqnNSAD.cpp index bdddffcdc..140baab23 100644 --- a/applications/OptimalControl/mhdopt/EqnNSAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnNSAD.cpp @@ -139,7 +139,7 @@ const int NonStatNSAD = (int) ml_prob.GetInputParser().get("NonStatNSAD"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -367,7 +367,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/OptLoop.cpp b/applications/OptimalControl/mhdopt/OptLoop.cpp index fa6a2fc8c..fc7e88df9 100644 --- a/applications/OptimalControl/mhdopt/OptLoop.cpp +++ b/applications/OptimalControl/mhdopt/OptLoop.cpp @@ -560,7 +560,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - currelem.SetDofobjConnCoords(mesh->_iproc,iel); + currelem.SetDofobjConnCoords(mesh->_iproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/EqnNS.cpp b/applications/OptimalControl/tempopt/EqnNS.cpp index caae14939..c53e44179 100644 --- a/applications/OptimalControl/tempopt/EqnNS.cpp +++ b/applications/OptimalControl/tempopt/EqnNS.cpp @@ -143,7 +143,7 @@ currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -429,7 +429,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/EqnT.cpp b/applications/OptimalControl/tempopt/EqnT.cpp index 7210a0189..cc6d9afd6 100644 --- a/applications/OptimalControl/tempopt/EqnT.cpp +++ b/applications/OptimalControl/tempopt/EqnT.cpp @@ -178,7 +178,7 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -461,7 +461,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/OptLoop.cpp b/applications/OptimalControl/tempopt/OptLoop.cpp index 864f9efe2..960f915d2 100644 --- a/applications/OptimalControl/tempopt/OptLoop.cpp +++ b/applications/OptimalControl/tempopt/OptLoop.cpp @@ -137,7 +137,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S xyz_refbox._ndof = mymsh->el->GetElementDofNumber(ZERO_ELEM,BIQUADR_FE); xyz_refbox.Allocate(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -269,7 +269,7 @@ double ComputeNormControl (const uint Level, const MultiLevelMeshTwo* mesh, cons //loop over the geom el types const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/src/equations/BoundaryConditions.cpp b/src/equations/BoundaryConditions.cpp index 300b416d8..72f6ab815 100644 --- a/src/equations/BoundaryConditions.cpp +++ b/src/equations/BoundaryConditions.cpp @@ -233,7 +233,7 @@ void BoundaryConditions::GenerateBdc() { CurrentElem currelem(iel,Level,BB,_dofmap->_eqn,_dofmap->_mesh,_dofmap->_eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); - currelem.SetDofobjConnCoords(isubd,iel); + currelem.SetDofobjConnCoords(isubd); currelem.SetMidpoint(); for (uint ivar=0; ivar< _dofmap->_n_vars; ivar++) bc_flag[ivar] = DEFAULT_BC_FLAG; //this is necessary here to re-clean! diff --git a/src/equations/CurrentElem.cpp b/src/equations/CurrentElem.cpp index b0904029b..28020ecde 100644 --- a/src/equations/CurrentElem.cpp +++ b/src/equations/CurrentElem.cpp @@ -228,14 +228,14 @@ void CurrentElem::PrintOrientation() const { } // ===================================================================================== - void CurrentElem::SetDofobjConnCoords(const uint isubd_in,const uint iel) { + void CurrentElem::SetDofobjConnCoords(const uint isubd_in) { const uint mydim = _mesh.get_dim(); const uint el_nnodes = _el_conn.size(); for (uint n=0; nGetNDofs(); xyz.Allocate(); - currelem.SetDofobjConnCoords(myproc,iel); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); From b1bbdb49c37a351b04f09552f35d4d3715f7372c Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 12:51:11 -0500 Subject: [PATCH 05/20] Cleaned myproc in SetDofobjs function --- applications/OptimalControl/mhdopt/EqnMHD.cpp | 2 +- applications/OptimalControl/mhdopt/EqnMHDAD.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnMHDCONT.cpp | 4 ++-- applications/OptimalControl/mhdopt/OptLoop.cpp | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/applications/OptimalControl/mhdopt/EqnMHD.cpp b/applications/OptimalControl/mhdopt/EqnMHD.cpp index 0f752a5f6..ebab9a657 100644 --- a/applications/OptimalControl/mhdopt/EqnMHD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHD.cpp @@ -449,7 +449,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp index 3c27fd371..c8c6beb57 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp @@ -140,7 +140,7 @@ const int NonStatMHDAD = (int) ml_prob.GetInputParser().get("NonStatMHDAD"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -364,7 +364,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp index 237656098..f52dc180f 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp @@ -138,7 +138,7 @@ using namespace femus; currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -410,7 +410,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(ml_prob.GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/OptLoop.cpp b/applications/OptimalControl/mhdopt/OptLoop.cpp index fc7e88df9..1e9489546 100644 --- a/applications/OptimalControl/mhdopt/OptLoop.cpp +++ b/applications/OptimalControl/mhdopt/OptLoop.cpp @@ -511,8 +511,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint mesh_vb = VV; Mesh *mymsh = eqn->GetMLProb()._ml_msh->GetLevel(Level); - // processor index - const uint myproc = mesh->_iproc; + const unsigned myproc = mymsh->processor_id(); // geometry ----- const uint space_dim = mesh->get_dim(); @@ -560,7 +559,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - currelem.SetDofobjConnCoords(mesh->_iproc); + currelem.SetDofobjConnCoords(myproc); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); From 84e913aee3ee326e007fe6b710f286b54a37f772 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 13:15:11 -0500 Subject: [PATCH 06/20] Removed proc argument from SetDofobjs --- applications/OptimalControl/fe_test/EqnT.cpp | 4 ++-- applications/OptimalControl/mhdopt/EqnMHD.cpp | 8 ++++---- applications/OptimalControl/mhdopt/EqnMHDAD.cpp | 8 ++++---- applications/OptimalControl/mhdopt/EqnMHDCONT.cpp | 8 ++++---- applications/OptimalControl/mhdopt/EqnNS.cpp | 8 ++++---- applications/OptimalControl/mhdopt/EqnNSAD.cpp | 8 ++++---- applications/OptimalControl/mhdopt/OptLoop.cpp | 4 ++-- applications/OptimalControl/tempopt/EqnNS.cpp | 8 ++++---- applications/OptimalControl/tempopt/EqnT.cpp | 8 ++++---- applications/OptimalControl/tempopt/OptLoop.cpp | 8 ++++---- src/equations/BoundaryConditions.cpp | 5 +++-- src/equations/CurrentElem.cpp | 11 ++++++----- src/equations/CurrentElem.hpp | 5 +++-- src/equations/SystemTwo.cpp | 7 ++++--- src/utils/Math.hpp | 4 ++-- 15 files changed, 54 insertions(+), 50 deletions(-) diff --git a/applications/OptimalControl/fe_test/EqnT.cpp b/applications/OptimalControl/fe_test/EqnT.cpp index 16c05278e..0b9773c09 100644 --- a/applications/OptimalControl/fe_test/EqnT.cpp +++ b/applications/OptimalControl/fe_test/EqnT.cpp @@ -65,7 +65,7 @@ for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -106,7 +106,7 @@ currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHD.cpp b/applications/OptimalControl/mhdopt/EqnMHD.cpp index ebab9a657..8659bd13b 100644 --- a/applications/OptimalControl/mhdopt/EqnMHD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHD.cpp @@ -71,7 +71,7 @@ void GenMatRhsMHD(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -155,7 +155,7 @@ void GenMatRhsMHD(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gr currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -359,7 +359,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -449,7 +449,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp index c8c6beb57..16c00ffae 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDAD.cpp @@ -67,7 +67,7 @@ const int NonStatMHDAD = (int) ml_prob.GetInputParser().get("NonStatMHDAD"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -140,7 +140,7 @@ const int NonStatMHDAD = (int) ml_prob.GetInputParser().get("NonStatMHDAD"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -321,7 +321,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -364,7 +364,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp index f52dc180f..609b375ae 100644 --- a/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp +++ b/applications/OptimalControl/mhdopt/EqnMHDCONT.cpp @@ -77,7 +77,7 @@ using namespace femus; for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -138,7 +138,7 @@ using namespace femus; currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -373,7 +373,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -410,7 +410,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnNS.cpp b/applications/OptimalControl/mhdopt/EqnNS.cpp index 03995deaf..bdf609622 100644 --- a/applications/OptimalControl/mhdopt/EqnNS.cpp +++ b/applications/OptimalControl/mhdopt/EqnNS.cpp @@ -159,7 +159,7 @@ const int NonStatNS = (int) ml_prob.GetInputParser().get("NonStatNS"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -250,7 +250,7 @@ const int NonStatNS = (int) ml_prob.GetInputParser().get("NonStatNS"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -547,7 +547,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0; iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -601,7 +601,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/EqnNSAD.cpp b/applications/OptimalControl/mhdopt/EqnNSAD.cpp index 140baab23..e30b5d992 100644 --- a/applications/OptimalControl/mhdopt/EqnNSAD.cpp +++ b/applications/OptimalControl/mhdopt/EqnNSAD.cpp @@ -66,7 +66,7 @@ const int NonStatNSAD = (int) ml_prob.GetInputParser().get("NonStatNSAD"); for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -139,7 +139,7 @@ const int NonStatNSAD = (int) ml_prob.GetInputParser().get("NonStatNSAD"); currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -327,7 +327,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -367,7 +367,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/mhdopt/OptLoop.cpp b/applications/OptimalControl/mhdopt/OptLoop.cpp index 1e9489546..1bf442904 100644 --- a/applications/OptimalControl/mhdopt/OptLoop.cpp +++ b/applications/OptimalControl/mhdopt/OptLoop.cpp @@ -526,7 +526,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); @@ -559,7 +559,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/EqnNS.cpp b/applications/OptimalControl/tempopt/EqnNS.cpp index c53e44179..0729cea6f 100644 --- a/applications/OptimalControl/tempopt/EqnNS.cpp +++ b/applications/OptimalControl/tempopt/EqnNS.cpp @@ -83,7 +83,7 @@ for (int iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -143,7 +143,7 @@ currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -378,7 +378,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0; iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -429,7 +429,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/EqnT.cpp b/applications/OptimalControl/tempopt/EqnT.cpp index cc6d9afd6..a7a9f3818 100644 --- a/applications/OptimalControl/tempopt/EqnT.cpp +++ b/applications/OptimalControl/tempopt/EqnT.cpp @@ -121,7 +121,7 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -178,7 +178,7 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -411,7 +411,7 @@ for (uint fe = 0; fe < QL; fe++) { for (uint iel=0;iel < (nel_e - nel_b) ; iel++) { - CurrentElem currelem(iel,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); + CurrentElem currelem(iel,myproc,Level,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -461,7 +461,7 @@ for (uint fe = 0; fe < QL; fe++) { currelem.Mat().zero(); currelem.Rhs().zero(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/applications/OptimalControl/tempopt/OptLoop.cpp b/applications/OptimalControl/tempopt/OptLoop.cpp index 960f915d2..71bfac0a9 100644 --- a/applications/OptimalControl/tempopt/OptLoop.cpp +++ b/applications/OptimalControl/tempopt/OptLoop.cpp @@ -101,7 +101,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); @@ -137,7 +137,7 @@ double ComputeIntegral (const uint Level, const MultiLevelMeshTwo* mesh, const S xyz_refbox._ndof = mymsh->el->GetElementDofNumber(ZERO_ELEM,BIQUADR_FE); xyz_refbox.Allocate(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); @@ -240,7 +240,7 @@ double ComputeNormControl (const uint Level, const MultiLevelMeshTwo* mesh, cons for (int iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,eqn,*mesh,eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,eqn->GetMLProb().GetQrule(currelem.GetDim())); @@ -269,7 +269,7 @@ double ComputeNormControl (const uint Level, const MultiLevelMeshTwo* mesh, cons //loop over the geom el types const uint el_ngauss = eqn->GetMLProb().GetQrule(currelem.GetDim()).GetGaussPointsNumber(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); diff --git a/src/equations/BoundaryConditions.cpp b/src/equations/BoundaryConditions.cpp index 72f6ab815..6c83d13b1 100644 --- a/src/equations/BoundaryConditions.cpp +++ b/src/equations/BoundaryConditions.cpp @@ -228,12 +228,13 @@ void BoundaryConditions::GenerateBdc() { for (uint isubd=0; isubd<_dofmap->_mesh._NoSubdom; ++isubd) { uint iel_b = _dofmap->_mesh._off_el[BB][ _dofmap->_mesh._NoLevels*isubd + Level]; uint iel_e = _dofmap->_mesh._off_el[BB][ _dofmap->_mesh._NoLevels*isubd + Level+1]; + for (uint iel=0; iel < (iel_e - iel_b); iel++) { - CurrentElem currelem(iel,Level,BB,_dofmap->_eqn,_dofmap->_mesh,_dofmap->_eqn->GetMLProb().GetElemType()); + CurrentElem currelem(iel,isubd,Level,BB,_dofmap->_eqn,_dofmap->_mesh,_dofmap->_eqn->GetMLProb().GetElemType()); currelem.SetMesh(mymsh); - currelem.SetDofobjConnCoords(isubd); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); for (uint ivar=0; ivar< _dofmap->_n_vars; ivar++) bc_flag[ivar] = DEFAULT_BC_FLAG; //this is necessary here to re-clean! diff --git a/src/equations/CurrentElem.cpp b/src/equations/CurrentElem.cpp index 28020ecde..c5dea14bd 100644 --- a/src/equations/CurrentElem.cpp +++ b/src/equations/CurrentElem.cpp @@ -27,14 +27,15 @@ namespace femus { - CurrentElem::CurrentElem(const uint iel_in, const uint level, const uint vb, const SystemTwo * eqn_in, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type_in ): + CurrentElem::CurrentElem(const uint iel_in, const uint iproc_in, const uint level, const uint vb, const SystemTwo * eqn_in, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type_in ): _eqn(eqn_in), _mesh(mesh), _dim(_mesh.get_dim()-vb), _elem_type(elem_type_in[mesh.get_dim()-vb -1]), _mesh_vb(vb), _Level(level), - _iel(iel_in) + _iel(iel_in), + _proc(iproc_in) { //========== Current "Geometric Element" ======================== @@ -228,14 +229,14 @@ void CurrentElem::PrintOrientation() const { } // ===================================================================================== - void CurrentElem::SetDofobjConnCoords(const uint isubd_in) { + void CurrentElem::SetDofobjConnCoords() { const uint mydim = _mesh.get_dim(); const uint el_nnodes = _el_conn.size(); for (uint n=0; n > & elem_type); + CurrentElem(const uint iel_in, const uint iproc_in, const uint level, const uint vb, const SystemTwo*, const MultiLevelMeshTwo& mesh, const std::vector< std::vector > & elem_type); inline const uint GetVb() const { return _mesh.get_dim() - _dim; @@ -81,7 +81,7 @@ class CurrentQuantity; return _KeM; } - void SetDofobjConnCoords(const uint isubd_in); + void SetDofobjConnCoords(); void SetMidpoint(); @@ -136,6 +136,7 @@ class CurrentQuantity; const uint _Level; //the level to which the element belongs const uint _iel; //the index of the element (input for the parallel partition) + const uint _proc; }; diff --git a/src/equations/SystemTwo.cpp b/src/equations/SystemTwo.cpp index 856767425..c9e267faa 100644 --- a/src/equations/SystemTwo.cpp +++ b/src/equations/SystemTwo.cpp @@ -229,18 +229,19 @@ void SystemTwo::Initialize() { for (uint Level = 0; Level< GetGridn(); Level++) { - Mesh *mymsh = GetMLProb()._ml_msh->GetLevel(Level); + Mesh *mymsh = GetMLProb()._ml_msh->GetLevel(Level); + const unsigned myproc = mymsh->processor_id(); uint iel_b = GetMLProb().GetMeshTwo()._off_el[VV][ GetMLProb().GetMeshTwo()._iproc*GetGridn() + Level ]; uint iel_e = GetMLProb().GetMeshTwo()._off_el[VV][ GetMLProb().GetMeshTwo()._iproc*GetGridn() + Level + 1]; for (uint iel=0; iel < (iel_e - iel_b); iel++) { - CurrentElem currelem(iel,Level,VV,this,GetMLProb().GetMeshTwo(),GetMLProb().GetElemType()); + CurrentElem currelem(iel,myproc,Level,VV,this,GetMLProb().GetMeshTwo(),GetMLProb().GetElemType()); currelem.SetMesh(mymsh); const uint el_dof_objs = NVE[ GetMLProb().GetMeshTwo()._geomelem_flag[currelem.GetDim()-1] ][BIQUADR_FE]; - currelem.SetDofobjConnCoords(GetMLProb().GetMeshTwo()._iproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); for (uint q=0; q < _UnknownQuantitiesVector.size() ; q++) { diff --git a/src/utils/Math.hpp b/src/utils/Math.hpp index 3ceba4799..92ba94e25 100644 --- a/src/utils/Math.hpp +++ b/src/utils/Math.hpp @@ -117,7 +117,7 @@ const uint myproc = ml_prob.GetMeshTwo()._iproc; for (uint iel=0; iel < (nel_e - nel_b); iel++) { - CurrentElem currelem(iel,Level,vb,NULL,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); //element without equation + CurrentElem currelem(iel,myproc,Level,vb,NULL,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); //element without equation currelem.SetMesh(mymsh); CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); @@ -130,7 +130,7 @@ const uint myproc = ml_prob.GetMeshTwo()._iproc; xyz._ndof = currelem.GetElemType(xyz._FEord)->GetNDofs(); xyz.Allocate(); - currelem.SetDofobjConnCoords(myproc); + currelem.SetDofobjConnCoords(); currelem.SetMidpoint(); currelem.ConvertElemCoordsToMappingOrd(xyz); From 3b456b0de49afe52740c5d31852c0c0bdca3cac1 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 15:39:42 -0500 Subject: [PATCH 07/20] Removed BB loop in EqnT in tempopt --- .../OptimalControl/fe_test/TempQuantities.cpp | 20 - .../OptimalControl/fe_test/TempQuantities.hpp | 4 - .../OptimalControl/mhdopt/OptQuantities.cpp | 19 - .../OptimalControl/mhdopt/OptQuantities.hpp | 5 - applications/OptimalControl/tempopt/EqnT.cpp | 383 +----------------- .../OptimalControl/tempopt/TempQuantities.cpp | 22 - .../OptimalControl/tempopt/TempQuantities.hpp | 5 - src/equations/CurrentElem.cpp | 2 +- src/equations/CurrentElem.hpp | 2 +- 9 files changed, 6 insertions(+), 456 deletions(-) diff --git a/applications/OptimalControl/fe_test/TempQuantities.cpp b/applications/OptimalControl/fe_test/TempQuantities.cpp index 5417eb89b..46ae20711 100644 --- a/applications/OptimalControl/fe_test/TempQuantities.cpp +++ b/applications/OptimalControl/fe_test/TempQuantities.cpp @@ -41,26 +41,6 @@ void Temperature::Function_txyz(const double/* t*/, const double* xp,double* tem } -// ================================================= - //the coordinates (x,y,z,t) of the VOLUME domain are NON-dimensional - //and the function value must be nondimensional as well - //-----Nonhomogeneous Neumann------- - // Qflux = - k grad(T) by definition -// QfluxDOTn>0: energy flows outside (cooling) QfluxDOTn<0: energy flows inside (heating) -void Temperature::heatflux_txyz(const double /*t*/, const double* /*xyz*/, double* qflux) const { - -// std::cout << "Temperature: Heatflux, check which coordinates are passed in here" << std::endl; -// Box* box= static_cast(_qtymap._phys._mesh->GetDomain()); -// const double thetaz = box->_domain_rtmap.get("thetaz"); - - qflux[0]=-2.1*0./**cos(thetaz)*/; - qflux[1]=0./**sin(thetaz)*/; - - return; - } - - - void Temperature::bc_flag_txyz(const double t, const double* xp, std::vector & bc_flag) const { // T' and its adjoint must be Dirichlet homogeneous everywhere on the boundary, by definition. diff --git a/applications/OptimalControl/fe_test/TempQuantities.hpp b/applications/OptimalControl/fe_test/TempQuantities.hpp index 46a528efa..561b4dd0b 100644 --- a/applications/OptimalControl/fe_test/TempQuantities.hpp +++ b/applications/OptimalControl/fe_test/TempQuantities.hpp @@ -20,10 +20,6 @@ class Temperature : public Quantity { void bc_flag_txyz(const double t, const double* xp, std::vector & flag) const; void initialize_xyz(const double* xp, std::vector & value) const; -//specific function - //this is the function of the IMPOSED DERIVATIVE of TEMPERATURE, aka heat flux - void heatflux_txyz(const double t,const double* xyz, double* qflux) const; - }; diff --git a/applications/OptimalControl/mhdopt/OptQuantities.cpp b/applications/OptimalControl/mhdopt/OptQuantities.cpp index d3456e826..b8adc619f 100644 --- a/applications/OptimalControl/mhdopt/OptQuantities.cpp +++ b/applications/OptimalControl/mhdopt/OptQuantities.cpp @@ -340,26 +340,7 @@ void Temperature::Function_txyz(const double t, const double* xp,double* temp) c } -// ================================================= -void Temperature::heatflux_txyz(const double t, const double* xyz, double* qflux) const { - //the coordinates (x,y,z,t) of the VOLUME domain are NON-DIMENSIONAL - //and the function value must be nondimensional as well - //-----Nonhomogeneous Neumann------- - // Qflux = - k grad(T) by definition -// QfluxDOTn>0: energy flows outside (cooling) QfluxDOTn<0: energy flows inside (heating) -std::cout << "Temperature: Heatflux, check which coordinates are passed in here" << std::endl; - Box* box = static_cast(_qtymap.GetMeshTwo()->GetDomain()); - const double thetaz = box->_domain_rtmap.get("thetaz"); - - qflux[0]=+700.*cos(thetaz); - qflux[1]=+700.*sin(thetaz); - #if (DIMENSION==3) - qflux[2]=0.; - #endif - - return; - } diff --git a/applications/OptimalControl/mhdopt/OptQuantities.hpp b/applications/OptimalControl/mhdopt/OptQuantities.hpp index 894369880..3cb29d85d 100644 --- a/applications/OptimalControl/mhdopt/OptQuantities.hpp +++ b/applications/OptimalControl/mhdopt/OptQuantities.hpp @@ -183,11 +183,6 @@ class Temperature : public Quantity { void Function_txyz(const double t, const double* xp,double* temp) const; -//specific function - //this is the function of the IMPOSED DERIVATIVE of TEMPERATURE, aka heat flux - void heatflux_txyz(const double t,const double* xyz, double* qflux) const; - - }; diff --git a/applications/OptimalControl/tempopt/EqnT.cpp b/applications/OptimalControl/tempopt/EqnT.cpp index a7a9f3818..7e5dd090c 100644 --- a/applications/OptimalControl/tempopt/EqnT.cpp +++ b/applications/OptimalControl/tempopt/EqnT.cpp @@ -102,10 +102,6 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri //==== AUXILIARY ============== std::vector dphijdx_g(space_dim); std::vector dphiidx_g(space_dim); - //-----Nonhomogeneous Neumann------ - // Qflux = - k grad(T) by definition -// QfluxDOTn>0: energy flows outside (cooling) QfluxDOTn<0: energy flows inside (heating) - std::vector Qflux_g(space_dim); my_system._LinSolver[Level]->_KK->zero(); my_system._LinSolver[Level]->_RESC->zero(); @@ -184,13 +180,7 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri currelem.ConvertElemCoordsToMappingOrd(xyz); currelem.TransformElemNodesToRef(ml_prob._ml_msh->GetDomain(),&xyz_refbox._val_dofs[0]); -//MY EQUATION -//the elements are, for every level: -// 1)DOF INDICES -// 2)BC FLAGS -// 3)BC VALUES -// 1) and 2) are taken in a single vector, 3) are considered separately - + currelem.SetElDofsBc(); Tempold.GetElemDofs(); @@ -198,25 +188,13 @@ void GenMatRhsT(MultiLevelProblem &ml_prob, unsigned Level, const unsigned &gri TAdj.GetElemDofs(); -// =============== -// Now the point is this: there are several functions of space -// which are expressed with respect to a reference frame -//ok, now that the dofs are filled for xyz_refbox, I can use the el_average -//Well, the alternative is to consider the elem in the refbox as - //either a Vect or a CurrentElem ! - //I could consider it as another element, but only with the geometrical part! - xyz_refbox.SetElemAverage(); - -int domain_flag = ElFlagControl(xyz_refbox._el_average,ml_prob._ml_msh); + int domain_flag = ElFlagControl(xyz_refbox._el_average,ml_prob._ml_msh); //==================== //===== FILL the DOFS of the EXTERNAL QUANTITIES: you must assure that for every Vect the quantity is set correctly // for every Vect it must be clear if it belongs to an equation or not, and which equation it belongs to; // this is usually made clear by the related QUANTITY. -// Now the main thing to check is the difference between Vect WITH QUANTITY and Vect WITHOUT QUANTITY. - // it is better to avoid using GetElDofs if the Vect is internal, only if external - //Do not use GetElDofs if you want to pick an intermediate dof... if ( vel._eqnptr != NULL ) vel.GetElemDofs(); else vel._qtyptr->FunctionDof(vel,time,&xyz_refbox._val_dofs[0]); @@ -250,7 +228,7 @@ for (uint fe = 0; fe < QL; fe++) { TAdj.val_g(); vel.val_g(); Tdes.val_g(); - + // always remember to get the dofs for the variables you use! // The point is that you fill the dofs with different functions... // you should need a flag to check if the dofs have been correctly filled @@ -401,133 +379,6 @@ for (uint fe = 0; fe < QL; fe++) { }//END VOLUME - { //BEGIN BOUNDARY // ***************************************************************** - - const uint mesh_vb = BB; - - 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,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); - currelem.SetMesh(mymsh); - CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); - - -//=========INTERNAL QUANTITIES (unknowns of the equation) ========= - CurrentQuantity Tempold(currgp); - Tempold._qtyptr = my_system.GetUnknownQuantitiesVector()[0]; - Tempold.VectWithQtyFillBasic(); - Tempold.Allocate(); - -//==================================== - CurrentQuantity Tlift(currgp); - Tlift._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_TempLift");//_UnknownQuantitiesVector[1]; - Tlift.VectWithQtyFillBasic(); - Tlift.Allocate(); - -//===================================== - CurrentQuantity TAdj(currgp); - TAdj._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_TempAdj");//_UnknownQuantitiesVector[2]; - 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(); - - //==================Quadratic domain, auxiliary, must be QUADRATIC!!! ========== - CurrentQuantity xyz_refbox(currgp); //no quantity - xyz_refbox._dim = space_dim; - xyz_refbox._FEord = MESH_ORDER; - xyz_refbox._ndof = myel->GetElementFaceDofNumber(ZERO_ELEM,ZERO_FACE,BIQUADR_FE); - xyz_refbox.Allocate(); - -//===============Tdes===================== - CurrentQuantity Tdes(currgp); - Tdes._qtyptr = ml_prob.GetQtyMap().GetQuantity("Qty_TempDes"); - Tdes.VectWithQtyFillBasic(); - Tdes.Allocate(); - -// ========================================== -// ========================================== - - currelem.Mat().zero(); - currelem.Rhs().zero(); - - currelem.SetDofobjConnCoords(); - currelem.SetMidpoint(); - - currelem.ConvertElemCoordsToMappingOrd(xyz); - currelem.TransformElemNodesToRef(ml_prob._ml_msh->GetDomain(),&xyz_refbox._val_dofs[0]); - - currelem.SetElDofsBc(); - - Tempold.GetElemDofs(); - Tlift.GetElemDofs(); - TAdj.GetElemDofs(); - - //============ FLAGS ================ -//in order to do the flag here, since it is a "TRUE" NATURAL BOUNDARY CONDITION, -//it only suffices that SOME OF THE NODES ARE with bc=1, AT LEAST ONE -int el_Neum_flag=0; - uint Neum_sum=0; - for (uint i=0; i < Tempold._ndof; i++) Neum_sum += currelem.GetBCDofFlag()[i]; - for (uint i=0; i < Tempold._ndof; i++) Neum_sum += currelem.GetBCDofFlag()[i + Tempold._ndof]; - if ( Neum_sum == 2*Tempold._ndof ) { el_Neum_flag=1; } - -//==================================== - - const uint el_ngauss = ml_prob.GetQrule(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 = dt*currgp.JacVectBB_g(xyz); - const double dtxJxW_g = det * ml_prob.GetQrule(currelem.GetDim()).GetGaussWeight(qp); -//=======end "COMMON SHAPE PART"=================================== - - xyz.val_g(); - - static_cast(ml_prob.GetQtyMap().GetQuantity("Qty_Temperature"))->heatflux_txyz(time,&xyz._val_g[0],&Qflux_g[0]); - - Tempold.val_g(); //For the penalty Dirichlet //i need this for interpolating the old function at the gauss point - - double QfluxDn_g=Math::dot( &Qflux_g[0],currgp.get_normal_ptr(),space_dim); - - for (uint i=0; i_KK->add_matrix(currelem.Mat(),currelem.GetDofIndices()); - my_system._LinSolver[Level]->_RESC->add_vector(currelem.Rhs(),currelem.GetDofIndices()); - - } - // end of BDRYelement loop - - - }//END BOUNDARY - my_system._LinSolver[Level]->_KK->close(); my_system._LinSolver[Level]->_RESC->close(); @@ -541,232 +392,6 @@ int el_Neum_flag=0; } -//====================== - //TODO here I have to put the right offset back - //This function must receive a BOUNDARY ELEMENT according to the common "FEMuS OFFSET NUMERATION LevxSubd", - //and it must yield the VOLUME ELEMENT NUMBER again according to the common "FEMuS OFFSET NUMERATION LevxSubd", - //so that it has embedded the information of "BELONGING TO SOME GIVEN SUBDOMAIN" - //We start from a Boundary element belonging to some subdomain, and we want to get the CORRESPONDING VOLUME ELEMENT NUMBER, - //which is the volume element number IN THE "FEMuS OFFSET NUMERATION LevxSubd" NUMERATION, - //so that once you have it you already know to which processor you belong! - // Now this vol_iel that we have is already ok, because it is in the ABSOLUTE FEMuS VOLUME ELEMENT ORDERING - // Actually, in the mesh file generated by GenCase we never wrote so far the list of numbers of the elements, - // we only needed to write the offsets, - //then we reconstruct the numbering later, - //then we reassociate that numbering to the connectivity. - //It is like the connectivities were "orphan" of their respective numbers, but actually the connectivities - //were printed exactly in the new Femus ordering, - //(as a matter of fact, the FEMuS mesh file forgets about the libmesh ordering but only considers the femus one), - //so actually their order INTRINSICALLY GIVES the Femus ordering. - - //Now there is another story: the _el_bdry_to_vol returns an element number in the - // Femus ABSOLUTE Element numbering. - // But, the ABSOLUTE element numbering is used to pick the CONNECTIVITIES. - //To go from the ABSOLUTE to the RELATIVE Femus element numbering, - //you have to do like this: - // first go from the RELATIVE boundary to the ABSOLUTE boundary - //then from the absolute boundary you get the ABSOLUTE VOLUME element number - //finally, from the ABSOLUTE VOLUME YOU WANT TO GET THE DofObject - //TODO the thing that does not seem very nice to me is that - //there is an _el_bdry_to_vol map for every LEVEL, - //but the elements are NOT numbered by level, but according to - //the ABSOLUTE element numbering - - - //this iel_femus is ABSOLUTE, but PER LEVEL - // the following is ABSOLUTE, not even per level, COMPLETELY ABSOLUTE - //maybe it would be better to have it absolute but per level -//====================== - - -//====================== -// Now the dof indices on the boundary must match with the -//dofs on the volume -//If with constant elements you do not have any dof on the boundary, -//then you have to think like this: -//What is the meaning of ENFORCING a BOUNDARY CONDITION VALUE? -//The meaning is that you enforce the TRACE of the VOLUME SHAPE FUNCTIONS. -//Then, of course, enforcing the TRACE means enforcing the VOLUME DOF, for constant FE. -//With nodes on the boundary, you are enforcing the DOF ITSELF, because -//among all the nodes there are some which are ONLY BOUNDARY NODES. -//Again, enforcing those boundary nodes can be seen as a form of ENFORCING the TRACE of the -//VOLUME SHAPE FUNCTIONS associated to those BOUNDARY NODES. -//In fact, you enforce the DOF values so that you "stretch" your TRACE at the boundary. - -//Now, the point here is that we have a VOLUME DOF, iel, associated to the CONSTANT FE, -//which may not belong to the current row actually -//Wait, so, do we need to have the VOLUME iel in the list of BOUNDARY DOF INDICES? -//"Boundary dof indices" are the -// "dof_indices that are involved in considering the current BOUNDARY ELEMENT" -//DOF_INDICES means "ROWS and COLUMNS" of the matrix - -//I dont care if i am in a BOUNDARY INTEGRAL and the dofs I involve -//are not "boundary dofs" strictly speaking... -//I am only interested in INVOLVING ALL THE DOFS THAT ARE INVOLVED . -//Now, I need a map that for every boundary element -//gives me the corresponding VOLUME element in the mesh. -//For every volume element, i can give you the children, which can be one or two... -//for every boundary element, there is only one father, -//so let us do a simple map that goes from CHILDREN to FATHER. -//That is not gonna be in terms of DOF but in terms of MESH. -//So we go from BOUNDARY iel to VOLUME iel. -//We need to do this in the Gencase because it is there -//where we can use the Libmesh functions - - - - - - - - //on the other hand consider that the penalty term does not have to appear whenever we are inside the domain -//the problem is that being inside the domain doesnt mean being Dirichlet, but here bc=0 may mean either being inside the domain -//or being a Dirichlet node. We want to put the penalty term where bc=0,but not inside the domain!!! -//so it takes a flag for setting dirichlet -//a flag for setting that we are inside the domain...no,but we already know that we are on the boundary, because -//the problem is that some nodes are BOTH VOLUME AND BOUNDARY. Or better, the SOME VOLUME NODES are also BOUNDARY NODES... -//no no - - - //this should be removed I think: yes it should, - //I mean its useless. With the PENALTY APPROACH you dont have a flag 0-1, but 0-\infty! - //therefore, you only have to distinguish two types of elements: - // - the ELEMENTS in which penalty=\infty, where the Dirichlet integral dominates over everything - // - the ELEMENTS with penalty=0, for which we know that bc=1 so the bc_alldofs in front is not needed! - //in the first ones the Dirichlet integral, AND ONLY IT, - //in the second ones the Neumann integral, TOGETHER WITH THE REST OF THE EQUATION - //instead in the NODAL DIRICHLET BCs, Neumann is still ELEMENTAL, so we must implement it - //with Neum_flag, NOT WITH bc_alldofs again! - //in conclusion, bc_alldofs must be eliminated FOREVER, because it's NODAL, and no nodal thing must be used for the boundary INTEGRALS! - //what remains is Neum_flag when you dont use penalty - //Well,actually we HAVE to use bc_alldofs[i] in case of NODAL DIRICHLET. In fact, in that case - //ALL THE ROWS OF THE LINEAR SYSTEM must be multiplied by bc_alldofs, because - // the bc_qldof flag means "in this row we are putting or not a Dirichlet nodal value" - // instead, el_Neum_flag means "For the ELEMENT we consider we must compute the integral" -// (and this computation will involve more than one row, so we cannot isolate the rows) -//clearly, this situation creates a little mismatch, because it may happen -//that the nodal bc-s are 1-1-0, -//but the integral should be computed over ALL the element -//it seems like you have to interpolate with three functions but you stop the sum to 2 instead. -//The missing term should appear in equation "i" in some column "j", but equation "i" in the nodal case -//has all zero except 1 on the diagonal -//Removing that node corresponds to TRUNCATING the INTERPOLATION of the SHAPE FUNCTIONS (i index) at that gauss point. -//That doesnt give any problem because the "coefficient that doesn't multiply anything" would have multiplied -// a zero, so no fear! - - - - - - - //PAY ATTENTION here because there may be a slight problem if some errors in the update of Tempold._val_g are there, -//like it happened with p_old for pressure in NS, which suggested us to use a FUNCTION instead of the previous value - -//el_Neum_flag and el_penalty are clearly ALTERNATIVE: -// el_Neum_flag == 1 el_penalty == 0 -// el_Neum_flag == 0 el_penalty == 10e20 -//This means that you shouldnt need multiplying by el_Neum_flag in the Neumann integral. -//Well actually I would like to keep some symmetry... -//In practice, the basis is writing the general equation... Then the issue is enforcing Dirichlet. -//In the NODAL case it is bc_alldofs that rules. -//In the PENALTY case it is el_penalty that rules - //So, in both cases computing el_Neum_flag is useless - //in the nodal case, el_Neum_flag is 1 when bc is 1 -//You may want to use el_Neum_flag to avoid adding the small Neum integral to the 10e20 row, -//if you're very fond of symmetry... -//yes, it is a minor thing but it is harmless -//well, actually it might be also good when the numbers of the heat flux are very high... -//So we'll leave it, it looks as stabilyzing... - -// T' should be equal to -T_0 -//The point is that T' is of course homogeneous at the boundary, by definition. -//The part that takes into account the boundary conditions is only T_0: -//now try to set the bc free for T': in this case you get exactly T' = -T_0; -// but this is not what you should get. -//Of course, if you have different boundary conditions for T' and T_0, -//they can never be equal... -//With the magnetic field we didnt have b' = - B_e -//now try to solve for different T_0 (change the equation, put the laplacian, get sthg else...) -//is it true that different T_0 of the SAME boundary conditions lead to the same solution T' + T_0 ? -//Given different lifting functions of the same boudnarty conditions, -//what is the condition sucj that we do not depend on the particular lifting function? -// For the magnetic field we had div B = 0, and we claimed that in that case -//the final sum was the same -//if we had div B != 0, the final result in terms of u and p was different -//maybe that case was particular only for Hartmann, which is a linear, simplified, MHD problem? - -//our previous claim was: the NS + MHD operators where in such a form that their action -// on various B_e was leading to results that were only dependent on the boundary conditions. -// We should check this thing more THEORETICALLY: considering how the operators act on the -//decomposition b+ B_e , where B_e is or not divergence-free. - -//in order to find the equivalence, i think that we have to check the OPERATOR we have. -//if the operator is not sensible to some class of functions, or better if the action of that -//operator does not "filter out" the particular choice of the lifting function -// and only retain the boundary condition values, -//then that is not a good operator for us. -// we need a sort of "independent operator", or "operator of boundary conditions" -//LAPLACIAN -//LAPLACIAN + TRNSPORT - -// The point is: if the solution of the operator for T is unique, -// then whatever T_0 you set you get another T', but the sum (T' + T_0) is unique. -// And, of course, if the boundary conditions are the same, the sum (T' + T_0) is the same. - -//Now with the lifting of B you ALSO needed that the lifting function was DIVERGENCE-FREE: -// otherwise, you were getting different solutions for (u,p). -//But, in this case you dont have any particular constraint on T_0 - -//For the temperature, you may say that if the solution of the state equations is unique -//for a given boundary condition, then whatever T_0 you get, the sum T' + T_0 is unique. - -// Numerically speaking, the only point would be to be sure that the matrix is diagonal dominant -// (coming from coercivity) for every lifting function: clearly we know that coercivity -// is fulfilled only for certain lifting functions, for a certain epsilon value wrt the viscosity. - -// PROBLEMA: Boundary conditions for the STATE, ADJOINT AND CONTROL variables -// Secondo la mia teoria, sia per T' sia per la sua aggiunta le condizioni al boundary devono essere FISSE. - -// Come e' giusto per un controllo d boundary, l'effetto prevalente deve avvenire vicino al boundary. -// Quindi il controllo di boundary agisce sul boundary del dominio, pertanto non puo' spingere molto all'interno. - -//$$$$$$$$$$$$$$$$ Come posso aumentare la spinta all'interno? - -//$$$$$$$$$$$$$ Il ruolo delle boundary conditions: slego T_0 al boundary, pero' le altre non sono slegate -// al boundary. Non slegherei T', magari proverei a slegare l'aggiunta, -// che da la spinta al controllo, che da la spinta allo stato - -//$$$$$$$$$$$$$$$ Provare a cambiare con il target, o con la condizione iniziale di Stato/Controllo - -//$$$$$$$$$$ E' chiaro che il controllo di boundary non e' cosi' efficace come il controllo distribuito - -//CONDIZIONI di NEUMANN con il metodo del lifting: come si fanno a mettere? -//Ad esempio nella parte non controllata vorrei poter mettere dei pezzi adiabatici. -//Allora qual e' il punto: -// l'imposizione del controllo e l'imposizione della condizione di neumann -// avverrebbero nello stesso modo, -// cioe' non fissando il valore in quel nodo. -// Allora come fa il sistema a capire se un pezzo di boundary della lifting function -// e' un pezzo di CONTROLLO o un pezzo di NEUMANN OMOGENEO ? - -// Aspetta: se tu nell'equazione della temperatura stai lasciando tutto libero e -// non stai fissando l'integrale di boundary, allora stai fissando tutto uguale a zero... -//Poi pero' il pezzo dell'integrale di boundary per T_0 va a finire nell'equazione del controllo -// quando fai la variazione delta T_0, quindi nell'equazione del controllo avresti -// l'integrale di boundary dell'aggiunta... -// e allora la domanda e': Qual e' la condizione di Neumann dell'aggiunta? - - - -//Poi, come si fa a tenere la temperatura positiva? Un algoritmo serio dovrebbe evitare temperature negative... -// Se pero' l'equazione e' adimensionale, i valori adimensionali possono venire anche negativi, -// dipende da come hai adimensionalizzato: l'importante e' che poi i valori finali siano positivi -// SE IO AGGIUNGO AI VINCOLI ANCHE UN VINCOLO DI DISUGUAGLIANZA DICENDO CHE LA TEMPERATURA SIA POSITIVA? - - - -// Succede questo (quasi paradossale): se la regione di controllo e' vicino al boundary control, -// converge fino ad alpha massimo molto piccolo. -// Se la regione di controllo e' lontana dal boundary control, allora converge fino ad un alpha max molto piu' grande. + #endif \ No newline at end of file diff --git a/applications/OptimalControl/tempopt/TempQuantities.cpp b/applications/OptimalControl/tempopt/TempQuantities.cpp index de46a999e..6a4fd381f 100644 --- a/applications/OptimalControl/tempopt/TempQuantities.cpp +++ b/applications/OptimalControl/tempopt/TempQuantities.cpp @@ -54,7 +54,6 @@ Velocity::Velocity(std::string name_in, QuantityMap& qtymap_in, uint dim_in, uin //============================================================= -///analytical velocity for Hartmann flow // difference between get_par and optsys: // in both cases you are "dynamic" somehow @@ -231,27 +230,6 @@ void Temperature::Function_txyz(const double/* t*/, const double* xp,double* tem } -// ================================================= - //the coordinates (x,y,z,t) of the VOLUME domain are NON-dimensional - //and the function value must be nondimensional as well - //-----Nonhomogeneous Neumann------- - // Qflux = - k grad(T) by definition -// QfluxDOTn>0: energy flows outside (cooling) QfluxDOTn<0: energy flows inside (heating) -void Temperature::heatflux_txyz(const double /*t*/, const double* /*xyz*/, double* qflux) const { - -// std::cout << "Temperature: Heatflux, check which coordinates are passed in here" << std::endl; -// Box* box= static_cast(_qtymap._phys._mesh->GetDomain()); -// const double thetaz = box->_domain_rtmap.get("thetaz"); - - qflux[0]=-2.1*0./**cos(thetaz)*/; - qflux[1]=0./**sin(thetaz)*/; - if (_qtymap.GetMeshTwo()->get_dim() == 3) { - qflux[2]=0.; - } - - return; - } - void Velocity::bc_flag_txyz(const double t, const double* xp, std::vector & bc_flag) const { diff --git a/applications/OptimalControl/tempopt/TempQuantities.hpp b/applications/OptimalControl/tempopt/TempQuantities.hpp index ba8d3e370..9135ecafc 100644 --- a/applications/OptimalControl/tempopt/TempQuantities.hpp +++ b/applications/OptimalControl/tempopt/TempQuantities.hpp @@ -22,11 +22,6 @@ class Temperature : public Quantity { void bc_flag_txyz(const double t, const double* xp, std::vector & flag) const; void initialize_xyz(const double* xp, std::vector & value) const; -//specific function - //this is the function of the IMPOSED DERIVATIVE of TEMPERATURE, aka heat flux - void heatflux_txyz(const double t,const double* xyz, double* qflux) const; - - }; //=============== diff --git a/src/equations/CurrentElem.cpp b/src/equations/CurrentElem.cpp index c5dea14bd..15f3f292a 100644 --- a/src/equations/CurrentElem.cpp +++ b/src/equations/CurrentElem.cpp @@ -292,7 +292,7 @@ void CurrentElem::ConvertElemCoordsToMappingOrd(CurrentQuantity& myvect) const { } //================================= -//TODO deprecated +/// @deprecated //This function is for NS type equations: //it computes the flags for pressure and stress integrals //based on the pressure nodes diff --git a/src/equations/CurrentElem.hpp b/src/equations/CurrentElem.hpp index 9f0eea449..9519ad843 100644 --- a/src/equations/CurrentElem.hpp +++ b/src/equations/CurrentElem.hpp @@ -126,8 +126,8 @@ class CurrentQuantity; // ======================================================================================== //========== Current Geometric Element: needs the MESH ======================== std::vector _el_conn; /// vector of the global nodes for that element [NNDS]; - std::vector _el_conn_new; uint _vol_iel_DofObj; /// i need to put the element also. + std::vector _el_conn_new; std::vector _xx_nds; /// vector of the node coordinates for that element [_spacedimension*NNDS]; // this must become a vect of vect std::vector _el_xm; /// element center point [_spacedimension]; const uint _dim; //spatial dimension of the current element (can be different from the mesh dimension!) From 806bda234de1b00606782a9542fd52edf984cd65 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 15:45:11 -0500 Subject: [PATCH 08/20] Removed all BB loops in tempopt --- applications/OptimalControl/tempopt/EqnNS.cpp | 147 ------------------ 1 file changed, 147 deletions(-) diff --git a/applications/OptimalControl/tempopt/EqnNS.cpp b/applications/OptimalControl/tempopt/EqnNS.cpp index 0729cea6f..21759687e 100644 --- a/applications/OptimalControl/tempopt/EqnNS.cpp +++ b/applications/OptimalControl/tempopt/EqnNS.cpp @@ -364,154 +364,7 @@ for (uint fe = 0; fe < QL; fe++) { }//END VOLUME - - // ***************************************************************** - // ***************************************************************** - // ***************************************************************** - - {//BEGIN BOUNDARY // ***************************************************************** - - const uint mesh_vb = BB; - - 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,BB,&my_system,ml_prob.GetMeshTwo(),ml_prob.GetElemType()); - currelem.SetMesh(mymsh); - CurrentGaussPointBase & currgp = CurrentGaussPointBase::build(currelem,ml_prob.GetQrule(currelem.GetDim())); - - -//=========INTERNAL QUANTITIES (unknowns of the equation) ================== - CurrentQuantity VelOld(currgp); - VelOld._qtyptr = my_system.GetUnknownQuantitiesVector()[QTYZERO]; //an alternative cannot exist, because it is an Unknown of This Equation - VelOld.VectWithQtyFillBasic(); - VelOld.Allocate(); - - const uint qtyzero_ord = VelOld._FEord; - const uint qtyzero_ndof = VelOld._ndof; -// Velocity* vel_castqtyptr = static_cast(VelOld._qtyptr); //casting for quantity-specific functions - -//========= - CurrentQuantity pressOld(currgp); - pressOld._qtyptr = my_system.GetUnknownQuantitiesVector()[QTYONE]; - pressOld.VectWithQtyFillBasic(); - pressOld.Allocate(); - - const uint qtyone_ord = pressOld._FEord; - const uint qtyone_ndof = pressOld._ndof; - - //order - const uint qtyZeroToOne_DofOffset = 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(); - - //==================Quadratic domain, auxiliary, must be QUADRATIC!!! ========== - CurrentQuantity xyz_refbox(currgp); - xyz_refbox._dim = space_dim; - xyz_refbox._FEord = MESH_ORDER; - xyz_refbox._ndof = myel->GetElementFaceDofNumber(ZERO_ELEM,ZERO_FACE,BIQUADR_FE); - xyz_refbox.Allocate(); - -//=== auxiliary Operators at the boundary -// double strainU_g['dimension']['dimension']; -// double strainUtrDn_g['dimension']; - - currelem.Mat().zero(); - currelem.Rhs().zero(); - - currelem.SetDofobjConnCoords(); - currelem.SetMidpoint(); - - currelem.ConvertElemCoordsToMappingOrd(xyz); - currelem.TransformElemNodesToRef(ml_prob._ml_msh->GetDomain(),&xyz_refbox._val_dofs[0]); - currelem.SetElDofsBc(); - - VelOld.GetElemDofs(); - pressOld.GetElemDofs(); - -//============ BC ======= - int press_fl = currelem.Bc_ComputeElementBoundaryFlagsFromNodalFlagsForPressure(VelOld,pressOld); -//========END BC============ - -//============================================================== -//================== GAUSS LOOP (qp loop) ====================== -//============================================================== - const uint el_ngauss = ml_prob.GetQrule(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 = dt*currgp.JacVectBB_g(xyz); - const double dtxJxW_g = det*ml_prob.GetQrule(currelem.GetDim()).GetGaussWeight(qp); -//=======end "COMMON SHAPE PART"=================================== - -//-------- pressure============== - //"predof" VS "post gauss method" - //pay attention to this fact: even if we are in the equation to which pressure is associated - //(pressure is an unknown here!), we might prefer using the FUNCTION instead, - //in order to get some values that DO NOT CHANGE with the solution - //so i'm using the FUNCTION of an UNKNOWN, it is not an external quantity - //clearly, this is ALTERNATIVE to the command - - - xyz_refbox.val_g(); - pressOld._qtyptr->Function_txyz(time,&xyz_refbox._val_g[0],&pressOld._val_g[0]); - - VelOld.val_g(); - -//============================================================== -//========= FILLING ELEMENT MAT/RHS (i loop) ==================== -//============================================================== - for (uint i=0; i_KK->add_matrix(currelem.Mat(),currelem.GetDofIndices()); - my_system._LinSolver[Level]->_RESC->add_vector(currelem.Rhs(),currelem.GetDofIndices()); - - - } - // end of BDRYelement loop - - - } - // END BOUNDARY ****************************** - my_system._LinSolver[Level]->_KK->close(); my_system._LinSolver[Level]->_RESC->close(); From e06d3a0466a54f3c8131d54936c0a4b7a81c63fb Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 18:09:05 -0500 Subject: [PATCH 09/20] Begin implementing new CurrentElem functions --- applications/OptimalControl/tempopt/EqnT.cpp | 3 -- src/equations/CurrentElem.cpp | 34 ++++++++++++++++++++ src/equations/CurrentElem.hpp | 7 ++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/applications/OptimalControl/tempopt/EqnT.cpp b/applications/OptimalControl/tempopt/EqnT.cpp index 7e5dd090c..578dde5af 100644 --- a/applications/OptimalControl/tempopt/EqnT.cpp +++ b/applications/OptimalControl/tempopt/EqnT.cpp @@ -61,9 +61,6 @@ // For the derivatives, I think the point is: you must pick the REAL dphidx in the SAME ORDER as you pick the CORRESPONDING DOFS. // Now, my point is: on a given row, are you sure that the code picks the correct dphidx? -//TODO what happens for STANDARD OUTPUTS? can we do in such a way that EVERYTHING is printed TO FILE? -// we should REDIRECT TO THE *SAME* FILE ALL THE std output and std errors of ALL THE LIBRARIES! - //NOW, PAY ATTENTION: The "iel" written as "iel=0; iel < (nel_e - nel_b);" is used for PICKING the CONNECTIVITY from the ELEMENT CONNECTIVITY MAP! // But, the iel as DofObject Index must be given in the correct form! // So, I will distinguish iel into iel_mesh and iel_DofObj: diff --git a/src/equations/CurrentElem.cpp b/src/equations/CurrentElem.cpp index 15f3f292a..0fbadcf6e 100644 --- a/src/equations/CurrentElem.cpp +++ b/src/equations/CurrentElem.cpp @@ -333,6 +333,40 @@ void CurrentElem::ConvertElemCoordsToMappingOrd(CurrentQuantity& myvect) const { return; } + + // ===================================================================================== +// void CurrentElem::SetDofobjConn_twoCoordsDof() { +// +// +// unsigned order_ind2 = ml_sol->GetSolutionType(ml_sol->GetIndex("U")); +// +// unsigned kel = mymsh->IS_Mts2Gmt_elem[iel]; +// short unsigned kelt = myel->GetElementType(kel); +// unsigned nve = myel->GetElementDofNumber(kel,order_ind2); +// +// _el_conn_new.resize(nve); +// +// for (unsigned i=0;iGetElementVertexIndex(kel,i)-1u):(kel+i*nel); +// unsigned inode=myel->GetElementVertexIndex(kel,i)-1u; + +// // dof metis +// unsigned inode_Metis=mymsh->GetMetisDof(inode,2); +// metis_node1[i]=mymsh->GetMetisDof(inode,SolType[2*dim]); +// /*metis_node2*/_el_conn_new[i]=inode_Metis; +// } +// +// +// +// return; +// } + + + + + + } //end namespace femus diff --git a/src/equations/CurrentElem.hpp b/src/equations/CurrentElem.hpp index 9519ad843..3b8a2616f 100644 --- a/src/equations/CurrentElem.hpp +++ b/src/equations/CurrentElem.hpp @@ -117,9 +117,9 @@ class CurrentQuantity; // ======================================================================================== //========== Current "EQUATION" Element (ql are TOGETHER ): needs the EQUATION ======================== + uint _el_n_dofs; DenseMatrix _KeM; DenseVector _FeM; - uint _el_n_dofs; std::vector _el_dof_indices; // this must become a vect of vect std::vector _bc_eldofs; // this must become a vect of vect @@ -191,6 +191,9 @@ class CurrentQuantity; //The curr geometric is basically filled with the MESH class //The curr fe is basically filled with the EQUATION class - +//==================================================== +// The differences with the other applications are that: +// the element matrix is split into blocks, while here it is only one +// Therefore, also the el_dof_indices and the bc_eldof flags are split as vector of vectors #endif \ No newline at end of file From 56b4238de262c59c13bbf0727b48b5ae52408592 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Tue, 10 Mar 2015 23:30:09 -0500 Subject: [PATCH 10/20] Understanding FSI assemble --- applications/FSI/include/FSIassembly.hpp | 2 +- src/equations/CurrentElem.cpp | 76 ++++++++++++++++++++---- src/equations/CurrentElem.hpp | 5 -- src/solution/MultiLevelSolution.cpp | 2 +- src/solution/MultiLevelSolution.hpp | 9 +-- 5 files changed, 71 insertions(+), 23 deletions(-) diff --git a/applications/FSI/include/FSIassembly.hpp b/applications/FSI/include/FSIassembly.hpp index 282cc6fde..ae65a1ea3 100644 --- a/applications/FSI/include/FSIassembly.hpp +++ b/applications/FSI/include/FSIassembly.hpp @@ -163,7 +163,7 @@ void AssembleMatrixResFSI(MultiLevelProblem &ml_prob, unsigned level, const unsi vector indexVAR(2*dim+1); //vector indCOORD(dim); vector indVAR(3*dim+1); - vector SolType(3*dim+1); + vector SolType(3*dim+1); /// @todo is this really 3*d + 1 or 2*d+1 would be enough? for(unsigned ivar=0; ivarGetNumberOfElements(); + +// elem * myel = _mesh_new->el; +// unsigned kel = _mesh_new->IS_Mts2Gmt_elem[_iel]; +// short unsigned kelt = myel->GetElementType(kel); + + +// unsigned order_ind = ml_sol->GetSolutionType(ml_sol->GetIndex("U")); +// unsigned nve = myel->GetElementDofNumber(kel,order_ind); // -// -// unsigned order_ind2 = ml_sol->GetSolutionType(ml_sol->GetIndex("U")); // -// unsigned kel = mymsh->IS_Mts2Gmt_elem[iel]; -// short unsigned kelt = myel->GetElementType(kel); -// unsigned nve = myel->GetElementDofNumber(kel,order_ind2); // // _el_conn_new.resize(nve); // // for (unsigned i=0;iGetElementVertexIndex(kel,i)-1u):(kel+i*nel); +// unsigned inode=(order_ind<3)?(myel->GetElementVertexIndex(kel,i)-1u):(kel+i*nel); // unsigned inode=myel->GetElementVertexIndex(kel,i)-1u; // // dof metis -// unsigned inode_Metis=mymsh->GetMetisDof(inode,2); -// metis_node1[i]=mymsh->GetMetisDof(inode,SolType[2*dim]); -// /*metis_node2*/_el_conn_new[i]=inode_Metis; +// /*metis_node2*/_el_conn_new[i] = mymsh->GetMetisDof(inode,BIQUADR_FE); +// metis_node1[i] = mymsh->GetMetisDof(inode,SolType[2*dim]); + + +// dofsVAR[j+dim][i]= mylsyspde->GetKKDof(indVAR[j+dim],indexVAR[j+dim],inode); + // } // // @@ -363,9 +384,40 @@ void CurrentElem::ConvertElemCoordsToMappingOrd(CurrentQuantity& myvect) const { // } - - - + // ===================================================================================== +// void CurrentElem::SetCoords_two() { +// +// for (unsigned i=0;iGetElementVertexIndex(kel,i)-1u; +// dof metis +// unsigned inode_Metis=mymsh->GetMetisDof(inode,2); +// metis_node2[i]=inode_Metis; +// +// unsigned inode_Metis=mymsh->GetMetisDof(inode,2); +// flag to know if the node "inode" lays on the fluid-solid interface +// solidmark[i]=myel->GetNodeRegion(inode); // to check +// for(int j=0; j_coordinate->_Sol[j])(inode_Metis) + (*mysolution->_Sol[indVAR[j]])(inode_Metis); +// Old coordinates (Moving frame) +// vx_old[j][i]= (*mymsh->_coordinate->_Sol[j])(inode_Metis) + (*mysolution->_SolOld[indVAR[j]])(inode_Metis); +// Fixed coordinates (Reference frame) +// vx_hat[j][i]= (*mymsh->_coordinate->_Sol[j])(inode_Metis); +// displacement dofs +// dofsVAR[j][i]= mylsyspde->GetKKDof(indVAR[j],indexVAR[j],inode); +// velocity dofs +// dofsVAR[j+dim][i]= mylsyspde->GetKKDof(indVAR[j+dim],indexVAR[j+dim],inode); +// } +// } +// +// +// +// +// return; +// } + + } //end namespace femus diff --git a/src/equations/CurrentElem.hpp b/src/equations/CurrentElem.hpp index 3b8a2616f..457e03e25 100644 --- a/src/equations/CurrentElem.hpp +++ b/src/equations/CurrentElem.hpp @@ -175,11 +175,6 @@ class CurrentQuantity; //in fact this is used for many element loop, but just to retrieve the geometrical properties //like coords, middle point, etc. -//Ok, so far we have VB, so if we want only BB or VV we should actually make a vector -// of two functions like this -//TODO i should TEMPLATIZE over VB!!! YES IT IS TRUE, IN FACT BASICALLY EVERYTHING -//DEPENDS ON VB, and when you use one you dont use the other!!! - //======================= //ok here we would need a "REFERENCE REAL ELEMENT" //the current element contains the absolute coordinates, diff --git a/src/solution/MultiLevelSolution.cpp b/src/solution/MultiLevelSolution.cpp index 64f396485..f2609fe7a 100644 --- a/src/solution/MultiLevelSolution.cpp +++ b/src/solution/MultiLevelSolution.cpp @@ -270,7 +270,7 @@ unsigned MultiLevelSolution::GetSolutionType(const char name[]) { index++; if (index==_SolType.size()) { cout<<"error! invalid name entry GetSolType(...)"< _solution; + /** Flag to tell whether the BC function has been set */ + bool _bdc_func_set; + /** This group of vectors has the size of the number of added solutions */ vector< vector > _boundaryconditions; vector< vector > _ishomogeneous; vector< vector > _nonhomogeneousbcfunction; - bool _bdc_func_set; - unsigned short _gridn; - vector _SolType; + vector _SolType; /* Tells the FE index */ vector _family; vector _order; vector _SolName; vector _BdcType; vector _SolTmorder; - vector _PdeType; + vector _PdeType; /*Tells whether the Solution is an unknown of a PDE or not*/ vector _TestIfPressure; vector _SolPairIndex; From 5c1edfd9e3a3540bdc2d8468559707442c2dd8de Mon Sep 17 00:00:00 2001 From: Sureka Pathmanathan Date: Tue, 24 Mar 2015 10:52:33 -0500 Subject: [PATCH 11/20] Added instructions to update fork master in github --- doc/devel_rules.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/doc/devel_rules.txt b/doc/devel_rules.txt index 83eed58d6..faf9cbc4d 100644 --- a/doc/devel_rules.txt +++ b/doc/devel_rules.txt @@ -96,4 +96,27 @@ git config --global user.email "name.surname@example.com" The maintainers will decide what to do with the pull request and possibly it will be merged to master Periodically, sync the master in the fork with the master in the main femus repository +################################## + +WORKFLOW for updating the master in the FORK from the master in the MAIN REPO + +In github: + +Go in the MAIN REPO +Click on "Pull requests" (on the right) +Click on "New pull request" (green button) +Click on "compare across forks" +The "base fork" is going to be the FORK master branch +The "head fork" is going to be the MAIN master branch +Click on "create pull request" +Add some title for it +Make sure that the branches can be AUTOMATICALLY MERGED (otherwise you have to solve the conflicts using command line...) +Click on "Merge pull request" (you find it by scrolling towards the bottom of the page) +Click on "Confirm merge" + +From command line: + +To be added + +################################## From 498bbb24f7cb85da550693d6bb7158f3907ecce3 Mon Sep 17 00:00:00 2001 From: Sureka Pathmanathan Date: Tue, 24 Mar 2015 15:38:07 -0500 Subject: [PATCH 12/20] Added Tri6 file in salome test --- doc/devel_rules.txt | 7 +++++++ unittests/testSalomeIO/input/OneTri6.med | Bin 0 -> 9533 bytes unittests/testSalomeIO/input/StudyTri6.hdf | Bin 0 -> 178448 bytes unittests/testSalomeIO/testSalomeIO.cpp | 2 +- 4 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 unittests/testSalomeIO/input/OneTri6.med create mode 100644 unittests/testSalomeIO/input/StudyTri6.hdf diff --git a/doc/devel_rules.txt b/doc/devel_rules.txt index faf9cbc4d..ba3572e64 100644 --- a/doc/devel_rules.txt +++ b/doc/devel_rules.txt @@ -120,3 +120,10 @@ From command line: To be added ################################## + +How to install HDFVIEW + +Follow the instruction in the HDFVIEW website + +At the end of the build process, you should have an hdfview.sh script inside the bin directory of your build. +You must open that script and change the INSTALLDIR variable with the path of this build (by default, /usr/local is in it) diff --git a/unittests/testSalomeIO/input/OneTri6.med b/unittests/testSalomeIO/input/OneTri6.med new file mode 100644 index 0000000000000000000000000000000000000000..67ae9c0a0edcd275dda519fc55b6d1117ee06c4f GIT binary patch literal 9533 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 literal 0 HcmV?d00001 diff --git a/unittests/testSalomeIO/testSalomeIO.cpp b/unittests/testSalomeIO/testSalomeIO.cpp index 7f348bff8..418e76ff8 100644 --- a/unittests/testSalomeIO/testSalomeIO.cpp +++ b/unittests/testSalomeIO/testSalomeIO.cpp @@ -13,7 +13,7 @@ int main(int argc,char **args) { FemusInit init(argc,args,MPI_COMM_WORLD); - std::string med_file = "OneQuad9.med"; + std::string med_file = "OneTri6.med"; std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file; const std::string infile = mystream.str(); From e34ac7c223a6675daebf4fbfec7256f211f58845 Mon Sep 17 00:00:00 2001 From: Sureka Pathmanathan Date: Tue, 24 Mar 2015 16:06:49 -0500 Subject: [PATCH 13/20] Found Tri6 Salome connectivity --- src/mesh/SalomeIO.cpp | 41 ++++++++++++----------- unittests/testSalomeIO/input/OneTri6.med | Bin 9533 -> 9533 bytes 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 09ad633c1..5431ac480 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -16,6 +16,7 @@ //local include #include "SalomeIO.hpp" #include "Mesh.hpp" +#include "GeomElTypeEnum.hpp" //C++ include #include @@ -35,29 +36,29 @@ namespace femus { - const unsigned SalomeIO::SalomeToFemusVertexIndex[6][27]= + const unsigned SalomeIO::SalomeToFemusVertexIndex[N_GEOM_ELS][27]= { { 4,16,0,15,23,11,7,19,3, 12,20,8,25,26,24,14,22,10, 5,17,1,13,21,9,6,18,2 - }, + }, //HEX27 { 0,4,1,6,5, 2,7,8,9,3 - }, + }, //TET10 { 3, 11,5, 9, 10,4, 12,17,14,15,16,13, 0, 8, 2, 6, 7, 1 - }, - {0,4,1,5,2,6,3,7,8}, - {0,3,1,4,2,5}, - {0,2,1} + }, //WEDGE18 + {0,4,1,5,2,6,3,7,8}, //QUAD9 + {0,1,2,3,4,5}, //TRI6 + {0,2,1} //EDGE3 }; -const unsigned SalomeIO::SalomeToFemusFaceIndex[6][6]= +const unsigned SalomeIO::SalomeToFemusFaceIndex[N_GEOM_ELS][6]= { {0,4,2,5,3,1}, {0,1,2,3}, @@ -193,9 +194,9 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords // SET NUMBER OF ELEMENTS mesh.SetNumberOfElements(n_elements); - int *conn_map5 = new int[dim_conn]; + int *conn_map = new int[dim_conn]; std::cout << " Number of elements in med file " << n_elements << std::endl; - status=H5Dread(dtset,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,conn_map5); + status=H5Dread(dtset,H5T_NATIVE_INT,H5S_ALL,H5S_ALL,H5P_DEFAULT,conn_map); if(status !=0) {std::cout << "SalomeIO::read: connectivity not found"; abort();} H5Dclose(dtset); @@ -209,28 +210,28 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords if (nve==27) { type_elem_flag[0]=type_elem_flag[3]=true; mesh.el->AddToElementNumber(1,"Hex"); - mesh.el->SetElementType(iel,0); + mesh.el->SetElementType(iel,HEX); } else if (nve==10) { type_elem_flag[1]=type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Tet"); - mesh.el->SetElementType(iel,1); + mesh.el->SetElementType(iel,TET); } else if (nve==18) { type_elem_flag[2]=type_elem_flag[3]=type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Wedge"); - mesh.el->SetElementType(iel,2); + mesh.el->SetElementType(iel,WEDGE); } else if (nve==9) { type_elem_flag[3]=true; mesh.el->AddToElementNumber(1,"Quad"); - mesh.el->SetElementType(iel,3); + mesh.el->SetElementType(iel,QUAD); } else if (nve==6 && mesh.GetDimension()==2) { type_elem_flag[4]=true; mesh.el->AddToElementNumber(1,"Triangle"); - mesh.el->SetElementType(iel,4); + mesh.el->SetElementType(iel,TRI); } else if (nve==3 && mesh.GetDimension()==1) { mesh.el->AddToElementNumber(1,"Line"); - mesh.el->SetElementType(iel,5); + mesh.el->SetElementType(iel,LINE); } else { std::cout<<"Error! Invalid element type in reading File!"< > &coords } for (unsigned i=0; iGetElementType(iel)][i]; - mesh.el->SetElementVertexIndex(iel,inode,conn_map5[iel+i*n_elements]); + mesh.el->SetElementVertexIndex(iel,inode,conn_map[iel+i*n_elements]); } } @@ -251,7 +252,7 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords // // // // // // add node pointers to the elements // // // // // for(int i=0; iset_node(eletype.nodes[i])= mesh.node_ptr(conn_map[Node_el*iel+i]); -// // // // // elem->set_node(eletype.nodes[i])= mesh.node_ptr(conn_map5[iel+i*n_elements]-1); +// // // // // elem->set_node(eletype.nodes[i])= mesh.node_ptr(conn_map[iel+i*n_elements]-1); // // // // // } // // // // // } @@ -271,7 +272,7 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords // clean - delete [] conn_map5; + delete [] conn_map; } @@ -345,7 +346,7 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords // unsigned iel,iface; // inf>>iel>>str2>>iface; // iel--; -// iface=SalomeIO::GambitToFemusFaceIndex[mesh.el->GetElementType(iel)][iface-1u]; +// iface=SalomeIO::SalomeToFemusFaceIndex[mesh.el->GetElementType(iel)][iface-1u]; // mesh.el->SetFaceElementIndex(iel,iface,value); // } // inf >> str2; diff --git a/unittests/testSalomeIO/input/OneTri6.med b/unittests/testSalomeIO/input/OneTri6.med index 67ae9c0a0edcd275dda519fc55b6d1117ee06c4f..b5071648c32c413034064e38a7ca57d01a4d3b9c 100644 GIT binary patch delta 748 zcmdn%wbyHc86VSG!B7OAY|pJQF(q1h`VH$zkmeruJ8yA)K0 zO$o?|$!EBDChuqTmpK+zzYVNN5#1bDMvy_9-Iz2PSwsZCJlR~#tj&(aH9(`HCAMsy zas`K7)e??r0t;|R%1`{JJXwUtQt9yjZU^k{NMjTbU|>k&n|x4IWOFl*52K=C&v9F9 z<_U&YfRq*r0hLNm=H?4$@!D~-YjUBG(&P?45j3Z7Ud6}4$PzhKrhoDuIk(CCB_$>c z2vJ{)!Ci@ClOkOB>hQ)V9ZPDgJp)w|M^gskVXoD=+L6V~39FKN2 zB>Ovicu)SwEjGDl33$zkmeruI@vYkO1 zn-Y)_lh1JROy1AvFLULnR1;W{BDy)Qj39$HyD@1pvIJDs{@z^7tj&(aH9(`HCH_U7 zYsX<%wS=#r(-|C+@)N%)PZr^^RN5-19)#T;X^a8_3=C;}lMjlDY;NZ9VN~=wQm%~6 zJi*WkkkUdSpi=3{+ Date: Tue, 24 Mar 2015 16:11:17 -0500 Subject: [PATCH 14/20] Found Quad9 Salome connectivity --- src/mesh/SalomeIO.cpp | 2 +- unittests/testSalomeIO/testSalomeIO.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 5431ac480..9d5adfd6d 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -52,7 +52,7 @@ namespace femus { 12,17,14,15,16,13, 0, 8, 2, 6, 7, 1 }, //WEDGE18 - {0,4,1,5,2,6,3,7,8}, //QUAD9 + {0,1,2,3,4,5,6,7,8}, //QUAD9 {0,1,2,3,4,5}, //TRI6 {0,2,1} //EDGE3 }; diff --git a/unittests/testSalomeIO/testSalomeIO.cpp b/unittests/testSalomeIO/testSalomeIO.cpp index 418e76ff8..7f348bff8 100644 --- a/unittests/testSalomeIO/testSalomeIO.cpp +++ b/unittests/testSalomeIO/testSalomeIO.cpp @@ -13,7 +13,7 @@ int main(int argc,char **args) { FemusInit init(argc,args,MPI_COMM_WORLD); - std::string med_file = "OneTri6.med"; + std::string med_file = "OneQuad9.med"; std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file; const std::string infile = mystream.str(); From 8331bd352aeff8037ada95497645690df2849a96 Mon Sep 17 00:00:00 2001 From: Sureka Pathmanathan Date: Tue, 24 Mar 2015 16:28:04 -0500 Subject: [PATCH 15/20] Found Edge3 Salome connectivity --- src/mesh/SalomeIO.cpp | 2 +- unittests/testSalomeIO/input/OneEdge3.med | Bin 0 -> 7317 bytes unittests/testSalomeIO/testSalomeIO.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 unittests/testSalomeIO/input/OneEdge3.med diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 9d5adfd6d..3ab5bb540 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -54,7 +54,7 @@ namespace femus { }, //WEDGE18 {0,1,2,3,4,5,6,7,8}, //QUAD9 {0,1,2,3,4,5}, //TRI6 - {0,2,1} //EDGE3 + {0,1,2} //EDGE3 }; diff --git a/unittests/testSalomeIO/input/OneEdge3.med b/unittests/testSalomeIO/input/OneEdge3.med new file mode 100644 index 0000000000000000000000000000000000000000..8d88efcdbd92db08e094d45527d6d69212f58057 GIT binary patch literal 7317 zcmeGgTWB0r^vtf=CYx!Ktf|`gAfX_ESWHZ75tMd!XC^y!=gwwkx5WG`TH9JAqAZmv z1c~4asUX!5(IWn6rJ4^Ps1)3f=0os_K~kz#r4?*#vD%*ogm}-Ld$%*0*@wwiYS;ra zcjn&ny64RKVO(Q_t%`6Qmjz-%xp)_eeDay5JwP- zF&Y91AkqbNXw!*i+W8@ss8&3!+DAFl2&I%@l}hZq5syDX@ev|xa5k*P?Ww3U155&c zE)Bo;-h3ulr8g?6v^EA;`PG$s0K#-Z#ziB(4ce(q=p%)02+@0(US1@f_>d6YgJh{` z9}*h-V@v-gSog~2>_F2*jGcuC^0&oMErg^qEc5>1;J0l|r5?9;@mZCs+p~c7q0r>m z3?hT5Y43)99}EP|4a*KW9OL5(93Gtdu0^v_8NdS&g7!;W6yMCN+@pQmi2MMGgIFSH zEj?9!plk#u>I{TlI!;9d)!40@Zb@WQ3e|{8re_Q8?;Yn9tsta)^!~cHuH(I!}rq&?0=R-KmN zUBuuMiNe@Tu-P@Sd3Vu*131BXZ2jrsz3`Z8qR?M_7QS+koE=NaRJ)cZ0MWt&oe#lzf(9>x(KdM^hr$Vv2mT7ezik~e(r5Z|KlJmz-rtFPXRDQg0 z;>+OjahKFiYn@%Rsz(qFh0`D4O6OYdil=}s7vB~k1;;oKQf7N_q+Enl11F-C;k3a? zA)S~)G8Cz!dkZV}0Jg%$R@g|RvXf5OhR+v0qKRn*25Jvda>y^5|O z_}zh`JxFEUk>P^sIE=^6{D!ua2V8|pMoY8805^t(ilHibV&*fJsp&N6=p?IJB%ZEK z>qT3$ea8_`nl*p;g@5fL86FAjA)VTk@EO35{SKpsK@1mu`SXw4q1!oKXL(%y;Xsd$?FB@tI z7-hq>sK*?Ir(Zd>1CMAhN1m;WxIV!@%busnOqnfUx}00*ugciz<+E33@6yNh?WlD{{c}kS|b1e literal 0 HcmV?d00001 diff --git a/unittests/testSalomeIO/testSalomeIO.cpp b/unittests/testSalomeIO/testSalomeIO.cpp index 7f348bff8..2e40ba990 100644 --- a/unittests/testSalomeIO/testSalomeIO.cpp +++ b/unittests/testSalomeIO/testSalomeIO.cpp @@ -13,7 +13,7 @@ int main(int argc,char **args) { FemusInit init(argc,args,MPI_COMM_WORLD); - std::string med_file = "OneQuad9.med"; + std::string med_file = "OneEdge3.med"; std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file; const std::string infile = mystream.str(); From 4ff22381738408f21d06416e528cd46ef5c4e6bd Mon Sep 17 00:00:00 2001 From: Sureka Pathmanathan Date: Tue, 24 Mar 2015 18:00:03 -0500 Subject: [PATCH 16/20] Understanding Hex27 salome connectivity --- src/mesh/SalomeIO.cpp | 37 +++++++++++++++++--- unittests/testSalomeIO/input/OneHex27.med | Bin 17809 -> 12829 bytes unittests/testSalomeIO/input/StudyHex27.hdf | Bin 177002 -> 177290 bytes unittests/testSalomeIO/testSalomeIO.cpp | 2 +- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 3ab5bb540..63386ec36 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -35,13 +35,42 @@ namespace femus { const uint SalomeIO::max_length = 100; ///@todo this length of the menu string is conservative enough... + //for the hex27, salome goes as follows: + //face X=-1, clockwise from cube center; + //face X=+1, anticlockwise from cube center; + const unsigned SalomeIO::SalomeToFemusVertexIndex[N_GEOM_ELS][27]= { - { - 4,16,0,15,23,11,7,19,3, - 12,20,8,25,26,24,14,22,10, - 5,17,1,13,21,9,6,18,2 + //from femus to salome + //1,2,4,3, + //5,6,8,7, + //9,12,11,10, centers lower face + //13,16,15,14, centers upper face + //18,17,19,20, vertical edges + //23,25,24,26, vertical faces + // 21, lower face + // 22, upper face + // 27 hex center + + //from femus to salome - subract one +// 0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,22,24,23,25, 20,21,26 + + //0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 //identity + //0,1,3,2,4,5,7,6,8,11,10,9, 12,15,14,13,17,16,18,19,22,24,23,25,20,21,26 //from femus to salome + //0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,24,25,20,22,21,23,26 //from salome to femus + + + { + 0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,24,25,20,22,21,23,26 +// 0,1,2,3,4,5,6,7, //vertices +// 8,9,10,11, //midpoints lower face +// 12,13,14,15,//midpoints upper face +// 16,17,18,19,//midpoints vertical edges +// 24,25, //opposite faces x direction +// 20,22, //opposite faces z direction +// 23,21, //opposite faces y direction +// 26 //hexahedron center }, //HEX27 { 0,4,1,6,5, diff --git a/unittests/testSalomeIO/input/OneHex27.med b/unittests/testSalomeIO/input/OneHex27.med index 1dc3ca57130c9e621d4c7ae53d48df8421ad49b5..b63a6b6951a1657e483ae708bc6f49118ccc8ceb 100644 GIT binary patch literal 12829 zcmeHNeQXp(6rXGDwX}!ONmA(fUGJ`lNK!S0s%ec_jS$la z0s$i!#fVMRL}Ef9$d?#2(a0Y(5`uz;L@S#3L5v}wV)~Db#yY>9dDq?Bk2~Nhw%$wj z-tNqMZ)V=izWL4Ddp_Xvk1d{3oL5xDhz2E1og+$WWktc!_P-+mUo5ZU!M@TK{k1l) z3^Jrhyf}}!7;{fyoQ(^r{z$yFNl}%UH>AXmOQUYC>0*V78gC7Iz0Y!ako!iI=KH-B}9PxWlWu9&W8GL$^SUf?eb9+Mj-XOzTpmes*!M zxYGNx3;y9$AbiH$bJ5coHMJ(Hvnp%$2zAyc`6y)jC$$~%#{yA?1(3(a4-Jvtnb+lv zR!b+!1xO1qsZf%7qvbDSoOg*Suwsed3#2E42-D7@fNQC^n-QQ5fgT&w%JHS5P2rEdK8Cr`S4OL09dut?aZ;Oa_WUBL@KoEy0G`_2Ir<>;zB;E%@@Mho4= zSJo=b0Go1t{$_u`*T5*CXvVuvKe8nmot1dh6jKp>k^;V9*jXTPpVexNk==JW` zl(MVvQU=ghZ867At+P|pborx|XEs~I$JMU!9P6y+s2)TI3UNL_jqhe-jR8R0#kUk8 z>lkMciY~K`lqo_PSWQE`9Zd=MwGK-g~EsD4is81BIa^U;LdZoT+Pxp@%#zQW##As zegMrcE-K@{u4b+a+A0CI^%xDFRvXOI0sLwZvYn2o)?8M94jzB>Px#VPrvoZce@Fuc zc!e;wu;Ob~BdyU`#2@5AC#WWrnCcB>*6Wm^#ZAi*D=jv#@5OXeL^z*#zK6N==V|@a ze60a(#yX_4hJ9)@94{NoGW+V}{U2o0HwxcEK%>DoPuHB;m_8J=gj;Y7<>a1syi?re zen*!FE-w<}vE%7RYo|x$-%I;;oa|>RPj*O;IO!9oa^h4@oXW`_mD6*k^(067#K{iv zR5>b7<)oh~pXoE%BRlj=`t)p9PjXbB`b_$E+)kd#hnG`|02v6R&I-vfs0KJ zLnxF-4C)-^iuzs4bUr;v{;&Mvz*ZLnx=S-7i0C|oS3EDyKfdY=DqqzqA4un015D^#B)3`+9xD2QI$IbciW_um%@*Jh6Utx(yUg1rc|e z$8~oKSqaHU^gQ;??r+bgZ(bfnzDaD@w>@pV;2&H9@?4fDUoy2O%{pLLIKl1?a z4Dby&Fb+838U$Kgz(TkP>p%`VkfVFl1K&Uf9D0OzkdHwQ2Kg84_sG@Y;s`;@)gW(! zI=q>62JirfwqcT z(I}6K5=BU9qxMHp(*mjrRcNaesp-F_5j1~js;W(^MoE>ZwwgAfN<_c!-h0gM?7e#z zSXac_k-j~5=AJp{%$eD_-<`FeZuJGK%BPnXl$I(fSFLi)Z???0ZuI=2yE@wHixt%T zpy@w}WDFHdqKA=a-IgA1Wvx<$xKYWQVQ-t7h@9XO zrA8Itvk*vC3P#eDsGgz}^M}%unC!p5@miC8?3vS9&D0c!`vR}ile&DctNA%qMlV*E_fP!mvhpRlt!t}%UrkBs^2VnPpQxUshG*V+`^pC+ zFJ56&zT8j-0`a(C$wK#FW%Y9g)bzhC{YIeG*Q8`aF^mtsx#Q^Q?(C0ur0uEPeMS|0 z!Ek1U#F}&q^g|1!{L1+JarFf>FeKwUIeMonl1RT}JT&65M4DGIYAD3~E?y(iaJp?H zo~}qR{f=QY(v$9$+sSA$B0a&hu&BV$@+F^vTQCDRON<)i$(0*owDaYs&fZ8!Q@MXs z2E5^5DCF;5>yJf$C4oJ3lUe`wOUHk410iKWeIs4zd#4fX-7X>jF!0JWd-^!wnFy{k z09MZ;FBInc0q=bMzSKJ@1lnnT)0FJ@xD=(1)%H83rj&)Hh|j^&T=Nk!nU9bTC{@?2 zGRU4%jcRd)T8v%Ue4H2q9=?#`Iuec9ZqzAC%`NG!jprsT_B~til*6K6n)g^QQK=JP zy=*l{qc2($WWPvg;inVKi8^YEYcFcy6}W2@q48E#h3bADZEkJ1e}AxiN230>s>}|* zeEUp^{UTBx&txReI>AW7AB%WH z*+s1lEuOX{6LsflbP3xFXjltthpSk`Fy>j|n zxy;RHwc{r@FISIz>b@0pg}e9~ic-Af^sHtO zN?qnz>LM>{`;4yV7N6XAi%af{Uy*M9MNf}Q?}hY^F)z9lks%z4uHRz;?!I5G-?`vA6SjweD8wf z`SCr#mw+08M;rG7bpQ{5X8<#SSpa`Qo(y?aUcP70jq&-fJaPgfVIFnU_Gz_*a-9jeZVGQGq45N3iJa5z&2nzumji$JOVrl z@G#^t;BjC#um{)+3<6I8`+)tx0bmF?2pj^Q1P%i{i_362yp_2{VQN{dKi|2XzhM-{ z{fo|Vj!=vPd*&5IbhUFshZAZpoYb=JqjQ^iBxHZ&XPpj*y}=Q#5tJ#luNGz)LJOA+ ziiDLigh9pojLc3+>ac6gt`L}90%FUi}l$-J^r_W?_s@+g; zE`-;rs!v)=A}{h8_&;Z$0RGAVK3w=9yA9xDneF6q#Q=F+5x`xp6yV?Nv7OwFdbI%i zlMk>zAB=?nxmvPqw$U~vZBsYdb_wdVO-bAIMced6+l+y>*-qQkD+eloDgex6l!poj z75*vQQ+TIv&U?|P4j>Vj3Ghov(!huA9AK;q^Tr%9C(H-O$nkP)94GT9W90nEIGIP# z6IafifgHWC5dBe{$k7WH|Fb6?Bu77)XIeOAiX?KhUW_v4q;j&TGUU2Bc6P0}WIYh} z{{GO<+{n~r%f84=58+EoOyxf28^wNXpO1&|hJP$dj2)S}gzTi`!HF+wO7>)G*50oT zxXq)GD3O`waRJ}uQ2LC|&-XlDJ^bFJT;}H3ILeKB_xUc@{Q`fWHpF*-l+M4d`mcGF z|IB9~pMg;xM;^gvs_;1SEk7V#teRQzy!9Gm!|Z}t~Ih zBrjbGkbiQ&t^-yAvw?>J^3X3W^l(QNFP9d^xXmkff>L|fU#4Tu~!3({ceDN0lfGxj+^BR~$# z*cl6BuK^hQbbzr>1B9o`IM~MfG7jdCxs!3wC;iJfm_O!D#v#02#u3B4IFJCkfYm@Z z&;zUi)&lE*^}q&TBhU-<0h@r$z!qRD&<_j%+koxB4q&W{ zd7Fi6nbZ4mEqUQOXRbM~TsIls56*EeQK-hEAD*7$xNE^csP zK8ML!%K&m+@`QFk+W9;rkC1lqYd*vEI{7r8q2$!$AiBK*wABKlN6u0N(D$7HeUr=6 zH#xYp(|1WyJAIQAiJsKyoBW8r`JmA4(RVQ*dR4e?1IV3Q0dk`-K+@9zkoSfFa$oXh z@}^Dz?8e}rx<2`AGa!7u0@vh8Vy7I}%K@=N-{g4oP2Nl2;awtb^?z9n}A+m zKX4G}12zJ>{${jo0ff)5!!>!o*jbC~^?=x6Y^wpr)(tSW9)Pi}0d@hqfk9v&Fa#U| a4g*I3x59P7b|<;dGF;-J`hF8Oc5U`z5qdy@quWGR6^Q=!54Ij zO;k!vIf|xSu{6y@zoyKZk^FiXGbK4wUzru+H&Z!&_U*OzIrlucfX?^L^>;XHpS||l zYyH>SYd`L}UjEut^{uHo3|Ad?hX3F>;UzCDzz4Cvf^hyIFLyfm-Cug1Gm#TAUxtHI zg>k6H`A5-W@NZ7-<8Q!)Bbu{KS;%ABg@Lo1n|%B+cEmNG?RU1XXRO6EJVE^7j>P8H zz&I;o5Sx6eMVpUBEI*zic8*a!1bHoE&tTJ=pYwj-{9HttHq%x~jW<6hEu)dYETzFP zcR1A}NG$Ga6r0k*3>j8h{0h{f8i{Qac7~}GW)f!#X#$w&L$Ad%?@OPV5nY(SR45c1 zCdQz`=GKWHU_X1Dz-ks}mK5Aqu(t4?RZCafo1K%FV)4ggM$;ayn$S91MCrlexvmHHS=n z5R=x+$RzHXWbd&J`U-wOmH8zV!N# zUS9N?Oih=p_oPK5y-f51mI3rK(`zujhR`d3UV-!qqE|4z4D{+puc7n;(INB-r5A`3 z7tR@x{{JG3oC-p*qV?-RV$|2h-Y(oej$92wgGjX*8QnE9wV$Ng(NFtHG34tZvOJRA zAB8zvzCkrDKS};rAO|Z8d4l)j6x`U4&lnp|{1V>`?hRA4KE!rWihk7U@chYBn-=Ex`u#xw=JN^WtUo2>qab#-*HF zo`QevC;Ajw6zQPQr$yL+hxHe?WVa;%!X*if5luxZH9^pT5-Mn(hQF@) z+ynIp7ik`Hn2x=PQVb9E7s$CFy;YMp?7?83Nj1m@P8%XFo@|^~EsaC&8$lSqV%h4F zcDK|ev5Pfm_T0WP0$p_41mV;no6 ztJ5xSp&}=0DpYvS9^ek|={u%);2cdGuHWLPsjxMg3ReW+O#`~bl6a2TaO&LV50?zV z;?R0uao0mj%9Fr|j19%B*A*75UB1?mtSd9Osp^?qRAuHyRXI-AK3-Q&(3V3iEMimw zXu?zcezeAU(B=1?8dCuSZ|dhbZwp2sl5wj9wuZB=>2N?t1m=N_qiW;K5f z=@LF?Bq=hVB9+%O=qY)09WTp#?NV7-&!5X{fsCcBJjgXFiunVfx)7!(n9ySurx-5L zDC&~Ea8dz7DlDHPWyGzyYN$HgK}8cA@^zEgOiIV%z(?;wMI4@{LeaTsBVnn-o3>M@ z4i>Svcm-1;=Qpwv#^q`y2K%Z#GP)HP+(_H%3Q;>_+~ZL;;11C+URpQ-m{h| zP*)-;fKtWKj~=XPS>uYCySve0s#_ftS1}zbOSuk~^?-y3Gs7%hI}Sv98PlV6gA7FJ zdNmLWx=~`KP8geJOv-9TJau%Wxuu+kjl4{{@KST=hyOry>Ew$$o)g#9hj>3O1y-f_ z=#micZM+n=L!5EE(C`55BQycICcoMRo* zd9t|Wl3_D_(q*zXDSeQgv(XSS=Cl#-*<0gW#nOYh;kR1V8LBj0oO|9IRf=D}eblgp ziVZDLfU6Tbyp5<@bY_Q$KR#x}-&BFIt!YO5^A_3JbOCPI4((Kc^SFnaYJCk?rK#Gz zDi;g9(GKzI`y0i@e@HPrp;+I8t z4J2GKIRP?^yfCh)6-WJNtKm5+;$mOfTOl7+;tRD-X97>TbD!mHOP_<0WX{>iixz$p zB)Cm{0W1i0&xzwNJcjJe?_8Kiov@k3gZFV?&OTK&DUW-rQf&A1>WkT$80s@$5JUew z67SjNboNIu@V#Nx3!hJrI0|M#dwu>g5^cV%z zQ76^fB!lD_Rt)3}vL*hTXe(2y)GBOqjq@$g2^Ol%D7O4E7l_;p4$iy>81=@UIyv1#+ARXan>r*=lwOw`*)JDIf}6)bq=mzTvN;V zK*I*J7@DEgVGm)oR0bYq)@ld>D#gV=oKaZrb;D924(%9>gB)U1hc!HiEi42J_iKDJQ9=Nl$A;LW)l{Es{ z#qY1qy5p;lqjDHisJb(t(~(PD^M=k*$Yb~2ucGGN*CP7(>RCaahdnOBN9?#dBk+%( z1+;YAZ?O2(Kj#Pj#~a>Px@8HX+7A~e-$)J&zO(IR_sWU&H!OIfKUp~#4Qu}NMg$71 z*)ZYlZbaU3bAv~d=~4tK3qV%!_|3s1^acnB(QP6|2+fcpa)uyYyXnA{m>??}gNBi- zLr|Ew?blfzKW({xFsU7aCXwk@)suVsqYy3yI#hQ=viqWp&|8#H)R)4n zR@qzbssp-6tZ5lbY-Y3~$i4eZeQA1(3nk+Rqu~DQq&XO#jSh$KnPmLr{v8{qPsq5J z>>P@Qkhd`E6M5hGdz=!ac?Z6m+=JjgK_oO71>-&eWPC8P+%X)E80cp|zX@J+!-NFG zr1AHi3nV#yXh>A!de79}+&e;QJ%Y!IGlZ9`S*-MBvB+Y@!`$L136cOTMl7y_TZ zT-bOE6lluP3yb>7ZHjwiif4h33W4+k~C3wOAn4e<7nF1d}|z7IQdsX1(esIc`E75R5^=jGGr z0OwU$sYv?i>b%I|%y}M>V{^xVRiQ~UW+%UB0cJt?Zs5vQz2U|-fRs0ZJK;rXZo0sn z;HC2DAMOkdgY=S3##qqY9^48r!N-eB+%Sq4{q+)~o-G-1xHt85!fLt`=0QdmAnw)- zDM-U7ziS4!I$MUIa_}4Y0q)=zxXb>7KHviX!6o|?_@E8&$u!i1e}M$4~Qb2(5U^7<^SB9k~(<- zJ;?L;^xbGXkEP5guEpj(hOKfe!RYl^DGzu#upkH^NFX4<>EK`RCHN8i3BCj$Ly&;~ z>9o#b0RqO4UXY$)4uI2O$nY==%fJpIr{d8RrlMprBo!?p570lzK|W4Jvr#OG98Yg?Wb=5GjpE70@n{Z8Ac<)xCnQm@ zrPxy(DfD2T-&5?d3YkEzrlQ1vc!8ctb>WM*gp!(6dPLojj*R5JG_(NQ?PTNxGy&UV zNznw9g>2-+1eA{L4&pHpJ&EjO>qJ!L?~rAsxWp!;IHvmk%XM=Q8FwG@BR8fX zV|m9Y{*?a}1O;UN1i}YCVNjXGcJaG~l?0)TfB7|n zB{g`4f6p1Ld-**{W^Bgv+a;ecsaSM~7FV*J$%3gU#XB>c_ZOh-UFcU^wdGzyoz%i# z;^2IAz_`MOKWUKoEE3!@pMoEMvPa^}(DA8oWgJcLcMiQW(s)Bz;M_%=D$U{dql{e; zigkPy%XxjnZ}?q?*8grgUbyLHPLzU|hm($Jx}izlo=$64h1X{4E2<9BiuK{dcZRB_ zrp0*VgBb`TyhSHWI%b%_RmhZ7r9l?`2)c<()zX8o3?6KXZM>}5K>E)?g}6GLyfp;7 z(nu})?#y7E#4-Tgxf=W@yOKde8YAf`iQ(soK(Y<3;X($bpJAS-hd(L!_u-^dAd)dbAnKOf9*3MWkqR5jdu3NN#>Tk|u2JL1m&P-5k5^l@SxI>1VqLRW-uc7?9W)zi~TLjxc%1mIAhxTyxjRAFPlFii`JoFL)d7SbuCFi`lL!D zDQOI|@X9(w!+tEKPcWxEoJ*Zzi*Oe-4FyaVfY!8>kpNm!9wPy?>UIb)l|a4+4L9A@X{ANSQ`I}m(PAngJm>|B8~4- zbnGDwZuK?0DTU4xOH2_BODpn&ale3l6IiI=gon7qcl+^8!irkt^HK zLhE3YDR)vyLBX`u`2}ljrE$5ru?dM}{7w`=nqEKwUU9j3i3LmGK`{CL1?1-$m!FuF zOwcZRtTJ*Z^7C>yY`OUfz%bS$FL#N9w;l5=-39D}`uJQ&ZY~oLKrT`#p1F>^_yR7_ zvI|*h4@+W`<6Ob=xZ!XmakpDdR3T?D|RCA(T?JK5vO7-hmO0IsOk6LqFy;$ zDEDm0zf-+(1!NT}J$pmP_|v*y z7qVs_9gkn^LpHjd%G^&64cebUKA2W)+ku9`ojx2v>r_RB=gKq4N;+Oe!^tBDP!e#5 z9z>(D-9{E2M0e56QtQ*m;s^M*d;7?1oPBD zAH>-h$7raGk4<)sa-JMKN-n(lQwjN!>d+J3TxJF_e*d=s`{S6e#*L<((CM7mqv5mxWTGM4C!S)L+bm5`f zFSsT$U$Uzp#baUCZ6*vq>17XoP5(y3;Rn?ATAzR@f!L9 ziN)SV_F|t!nrf;(;AF$zN<8p zyvaydwOv2LNLZ$29RrfDSsiatTD4{!9ocoEPukw5osEek8^2dNbA5e|r$%Z4Q?JB) ziO;(HQep7tS`R)s=L<2WSe$4eNg7M7|QdP5&W z)%57WVEz+;;9BEb&oOuasblZ68d)tzD=qSE6x-WgjMVP!T*K-o9S|%vR((hV>ldB< zuJ}3Lh7MY(sn-wpgv0iz`Te*IF==+wLtQGD$XZ`U!W?J>tr&4?B9(i zG5y#m8ye+qlx2O!Ab~i_YjdG<`C~>x9Hm_VlE+cWpDC@1qcKr#Mj69zY*aV+&56>E zG6lc6QSRcWm6&@Jp||H|3}>}`KzBm`w%J0k)1W0!#Bu-AW0 zX%+0xyMvu2w-=(iNpAafu)BhjZZmxe8@~tK;-B^1?c#s-M~=U#gu@-a4wIN7dI(?2 z%WY-q-2Z`FcpATFKma_)eqbcPlXjVr08jlDAUQl`9h6qV)7dRN*SdoTM{A=}3lCkq z>>{1N&@t{2O`@-N$#IUqbByF%Kib6xN=<;{lb|4)WTr>Z&o9#SN}6D@?3Z032M~6(b_`>SFT&ALxqi1 zhQneV4lcY{uERHPGiD5BShBmMmfQVQo%BHUrGP5iZ;W=A%d!PH|7R4rOySi=9G=x!3eUretz!yxf7TwgMoMX~Rd_|d@6Jy*3be{3)&S)xwzW0(w!5n}CK>@Rih8>Tdzu1oY@RG-DLUXuhJ6 z*THviU!{Wa^wU!sgbf_oO21V!Oi80^FJwrt1MDYbbO+d$Vc1lD_6P@7c8qEx!TORN zz3G&ePqo5kd=2a`o#J(Ts)aY>kR6@JPc@bA9uFzYQO0PK1g3>Br+|OjhA|TS;|K;) zSsPebjl4yBUNt{w2opVSll>*kzg^t3rHT3mq4N_BCoiKNcar`{yv869H~l>00g|1jQ`nV zK(amA%@}ukvig|YHQyXZmF02BfF5kqbj0F3uq8SPHU$Ozo?LQ47 zRrb?kqb^@V@-2D1t*gHo0I9Z~MkHIeO|ZFJH^N&ruUGwuosj>xdWEFUX z?xyOH_hB2)B|*B?79R+cnaOM*WH6Eqgb9pf17Q-7Qfj`3(kdW6bO!|e`3F8vfk<~Z z5ZZJ=uvEdm^ZMMTi+}iv$m*ER?T1%>;FI+bFPHLSm%}ulZ={N{IaF0PeG=b$vB_Xu z?^-?OYyi?{uEc5H%ZhbU@q8mKo={TQHEl@O(j&H`6074QZIV{)a2dxLi7#8nr`q^3 zjtdf>`Lb5tF=eO0I9QH`7oVzTF!z9`tkYaBVbjh{n`YYKhhlBhafV-baql!mE+hH2)U8O?%?slvda^QBzBN>*<-&0v9~j=V8}dRuGuAc5PtF3Xpw8 z_@p&0m-nA4A<=ELLH`Wyopue}wWQ$@I?JE_LhDG?7M@9#XZg!IKGn{i@ij<#T>e%o zPqigw9P;E{zl7;u^I8D>3c}#XVK~4juF3<_HGwzg(_%XKg`KfBQ-|r#Sn01zQt)eb zGOa>4jtSesosnWdyM?Qk@C+n<^YHG!Dmbsr2o_gX)Q^eM?0HR%)kU( zJ6F1biewk#6oa1wkzb#df8s;`n*nWD9eUtjRgIoCXjBVvXvUAE+Vuxrs=c&MQH`y@ zk{uf4bec6j!Zk~k08Tg>`Lo#VBoxP@webo^I6C{tNP92}>@zjyOxK z!)A{M_9K7ajGyvyjns(__aoKNr<@+JsD8^WC4RbXHw4lu#nhpTy;Zn#$AlyY+OX(eMwBeiIoYNQs4x7>|xq@I3;LamHc!$fM?j%CWY zlg7iLrYdRC{}rXE#0+rU+u zD}`O}L$z4u+^wj#i%#EL*<1SbHEGTCUCVx0XE4763i`;S!1_B@lw;lTvP=DAyI75^ zPTDK9$d`ujKBnP$YCppj>Wf(@b?8Z-8 z8yh)BVY1~ttQPs2r$XX1AE4^<$YSqCO>$_qIJNv}vU4A^xln3!8XB?x1;$Xnm(|D} z<5y{s=Qb8~@9131Rz&cBG#FaTvH0lCLE8V5!!><8*Gzw{MVBV`lPUuaV_D$iYrf*q z(c$OV literal 177002 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

?sSXcJvImdy$X}Z zP8%V@=<;}n$%B;DArJbEocSN0*tzD_=L%Wl(iv`3r#-=qwB|~Odh1H4tZF23(q08Pae*V+&-hfS{rcQQFd`Y zH#;?USnzvu2bStr=l@MY$11 z*Q-A>y&`3G=oJN@e=fGd-(Ans59JQzW^+^f%~8_7@HqqPTPY0l8?&RT@10gb-EXW^ z($z^9Hov**CX7D6|Jvp^DOEnz;Wy6ApDXf+XP@VR37s#G9Z-0$4f};J=*;E(_5Kd; zgNE1b!SntOFZY9<91HeCw3_4Z4aU2`>V0fqFkYwOJv$zZXK0}yOs`lAVRXIvuIUvi zwJDXZS7Gvaok^51x;(yT@*rhx$fMchK^R>gFPc0^Ssn7Q?iSY1-gALZ%KJ80_u5LB z>teofQ^@NZH(_x__aU91v{UuCf+M^(pm#rapLP3zTT1QriIzr~o#n0?VRXB4K~{Y` zDYfO5?svTF;Cm*6<Y7_u*A9l+mABbo5JtBvSDRfSr825Ef3K zP#x>k!gJzVJn#8`;~pLF=Rc{C&xtR#-?^v$Kl1B(|LIRFe9$!D8V}z1XZ8M_#}x88 z@k<}pyr1GQ-ni$3!FYU5{QR#3<8@j^jUNfd^J|Z{JWQ`x3t@D<`VXd8q|}-#U9ZCA z!Kb{0(dF^GCJ$29hCJe?P=wLt@eT7lq*O+gt{>LjQ~sPd<#|q=vNxvroH%7~Oj|zA z@?`v?{AZzId8(uwIlCh#Iuvm7pSB5~0!}J6b8FYk%+CGOQ;F6sGgAj+gVzmbhpx*G z#RkV_$F7^qy+76xFaB3R*fW=l?;o4X&BegcT9H7V$=KFI(?@b!4~|dIPEC$&9iBcg z|NgPr+|~oRBa#;8wk}Lf&d=xO=I6G`-{G;tz~4Erb#iKEVSelI{KCZTJqzQx)WnuU z69-}q3-Q)OBA$$=k}ZjhacxLv5^eERY1vyF-nt_@u>0z^EtxHe2KMCYhT+}W;XW&+ z9@Jr70(A-0B~X_@T>_OTfw1?)ZuykP=Uk`M_k}8P6j!fJ+!xwwRm2T8{#xm}E&trk zXCJeDnN18^XYuJKVf1yyW46vBr8cb6*A==?){sA6<3^ACmnq&giymh0Zv0H$-mO{X zK*wqCj++qn8GPj5mfAZjK4Bot-tl=YVRU=rhJG_x{`6Nb+w;P;sJrF*9Hv+FHiXgjDsFm3%IeT7%BWWS z)ngCpyx@L9eLsmKyf&cMU(HyzyT24{FJG;6!tBZhtAH@NUAe;S3MrLQb*!&WkMX^d z#xDfRzs2OU@ppppIt}mQF9ze$|2_QqU_9E1JD~9#%U|zfzCymMh`v#`lZw8o#=_ z{yWU?aMec`-Of&!T_L58Po?`|-H(u7>UGbTgXPaS>!q&*<8fX;|9ioB)vd*a)`#iU z*@j9OU9YB0uSltkDqXL_0?l5_fvO45p-7WZUuU}rJ=L?;zc$rZBcg*+q zW9t5UnF6gbboy`l1Nx7bj+fed#*u?3sQ+PhrQhlyjBZzc#q0_xl~J|Z*#VOWVRU(X M%j7}I>X66(54&BmH2?qr diff --git a/unittests/testSalomeIO/testSalomeIO.cpp b/unittests/testSalomeIO/testSalomeIO.cpp index 2e40ba990..e2f6b6715 100644 --- a/unittests/testSalomeIO/testSalomeIO.cpp +++ b/unittests/testSalomeIO/testSalomeIO.cpp @@ -13,7 +13,7 @@ int main(int argc,char **args) { FemusInit init(argc,args,MPI_COMM_WORLD); - std::string med_file = "OneEdge3.med"; + std::string med_file = "OneHex27.med"; std::ostringstream mystream; mystream << "./" << DEFAULT_INPUTDIR << "/" << med_file; const std::string infile = mystream.str(); From 57134343dc835ee1b43bf10a585130dfee397555 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Wed, 25 Mar 2015 09:56:01 -0500 Subject: [PATCH 17/20] Found HEX27 salome connectivity --- doc/devel_rules.txt | 2 ++ src/mesh/GambitIO.cpp | 4 +-- src/mesh/GambitIO.hpp | 5 +-- src/mesh/SalomeIO.cpp | 73 ++++++++++++++++++++++++------------------- src/mesh/SalomeIO.hpp | 6 ++-- 5 files changed, 51 insertions(+), 39 deletions(-) diff --git a/doc/devel_rules.txt b/doc/devel_rules.txt index ba3572e64..e19b64d73 100644 --- a/doc/devel_rules.txt +++ b/doc/devel_rules.txt @@ -127,3 +127,5 @@ Follow the instruction in the HDFVIEW website At the end of the build process, you should have an hdfview.sh script inside the bin directory of your build. You must open that script and change the INSTALLDIR variable with the path of this build (by default, /usr/local is in it) + +Another alternative to view the content of an HDF5 file is to use the 'h5dump' utility shipped with HDF5 (installed through PETSc, for instance) diff --git a/src/mesh/GambitIO.cpp b/src/mesh/GambitIO.cpp index a0a297887..45b16094f 100644 --- a/src/mesh/GambitIO.cpp +++ b/src/mesh/GambitIO.cpp @@ -24,7 +24,7 @@ namespace femus { - const unsigned GambitIO::GambitToFemusVertexIndex[6][27]= + const unsigned GambitIO::GambitToFemusVertexIndex[N_GEOM_ELS][27]= { { 4,16,0,15,23,11,7,19,3, @@ -46,7 +46,7 @@ namespace femus { }; -const unsigned GambitIO::GambitToFemusFaceIndex[6][6]= +const unsigned GambitIO::GambitToFemusFaceIndex[N_GEOM_ELS][6]= { {0,4,2,5,3,1}, {0,1,2,3}, diff --git a/src/mesh/GambitIO.hpp b/src/mesh/GambitIO.hpp index 4e5608133..28ec75567 100644 --- a/src/mesh/GambitIO.hpp +++ b/src/mesh/GambitIO.hpp @@ -19,6 +19,7 @@ // Local includes #include "MeshInput.hpp" +#include "GeomElTypeEnum.hpp" namespace femus { @@ -53,10 +54,10 @@ class GambitIO : public MeshInput private: /** Map from Gambit vertex index to Femus vertex index */ - static const unsigned GambitToFemusVertexIndex[6][27]; + static const unsigned GambitToFemusVertexIndex[N_GEOM_ELS][27]; /** Map from Gambit face index to Femus face index */ - static const unsigned GambitToFemusFaceIndex[6][6]; + static const unsigned GambitToFemusFaceIndex[N_GEOM_ELS][6]; }; diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 63386ec36..3e7b5b4a2 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -16,7 +16,6 @@ //local include #include "SalomeIO.hpp" #include "Mesh.hpp" -#include "GeomElTypeEnum.hpp" //C++ include #include @@ -35,43 +34,51 @@ namespace femus { const uint SalomeIO::max_length = 100; ///@todo this length of the menu string is conservative enough... - //for the hex27, salome goes as follows: - //face X=-1, clockwise from cube center; - //face X=+1, anticlockwise from cube center; + //How to determine a general connectivity: + //you have to align the element with respect to the x-y-z (or xi-eta-zeta) reference frame, + //and then look at the order in the med file. + //For every node there is a location, and you have to put that index in that x-y-z location. + //Look NOT at the NUMBERING, but at the ORDER! +// SALOME HEX27 +// 1------17-------5 +// /| /| +// / | / | +// 8 | 21 12 | +// / 9 22 / 13 +// / | / | +// 0------16-------4 | +// | 20 | 26 | 25 | +// | 2------18-|-----6 +// | / | / +// 11 / 24 15 / +// | 10 23 | 14 +// | / | / +// |/ |/ +// 3-------19------7 + +// TEMPLATE HEX27 (for future uses) +// X------X--------X +// /| /| +// / | / | +// X | X X | +// / X X / X +// / | / | +// X------X--------X | +// | X | X | X | +// | X------X--|-----X zeta +// | / | / ^ +// X / X X / | eta +// | X X | X | / +// | / | / | / +// |/ |/ |/ +// X-------X-------X -------> xi + const unsigned SalomeIO::SalomeToFemusVertexIndex[N_GEOM_ELS][27]= { - //from femus to salome - //1,2,4,3, - //5,6,8,7, - //9,12,11,10, centers lower face - //13,16,15,14, centers upper face - //18,17,19,20, vertical edges - //23,25,24,26, vertical faces - // 21, lower face - // 22, upper face - // 27 hex center - - //from femus to salome - subract one -// 0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,22,24,23,25, 20,21,26 - - //0,1,2,3,4,5,6,7,8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26 //identity - //0,1,3,2,4,5,7,6,8,11,10,9, 12,15,14,13,17,16,18,19,22,24,23,25,20,21,26 //from femus to salome - //0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,24,25,20,22,21,23,26 //from salome to femus - - { - 0,1,3,2,4,5,7,6,8,11,10,9,12,15,14,13,17,16,18,19,24,25,20,22,21,23,26 -// 0,1,2,3,4,5,6,7, //vertices -// 8,9,10,11, //midpoints lower face -// 12,13,14,15,//midpoints upper face -// 16,17,18,19,//midpoints vertical edges -// 24,25, //opposite faces x direction -// 20,22, //opposite faces z direction -// 23,21, //opposite faces y direction -// 26 //hexahedron center - }, //HEX27 + {4,7,3,0,5,6,2,1,15,19,11,16,13,18,9,17,12,14,10,8,23,25,22,24,20,21,26}, //HEX27 { 0,4,1,6,5, 2,7,8,9,3 diff --git a/src/mesh/SalomeIO.hpp b/src/mesh/SalomeIO.hpp index 97410af89..740c611b8 100644 --- a/src/mesh/SalomeIO.hpp +++ b/src/mesh/SalomeIO.hpp @@ -19,6 +19,8 @@ // Local includes #include "MeshInput.hpp" +#include "GeomElTypeEnum.hpp" + #ifdef HAVE_HDF5 #include "hdf5.h" #endif @@ -56,10 +58,10 @@ class SalomeIO : public MeshInput private: /** Map from Salome vertex index to Femus vertex index */ - static const unsigned SalomeToFemusVertexIndex[6][27]; + static const unsigned SalomeToFemusVertexIndex[N_GEOM_ELS][27]; /** Map from Salome face index to Femus face index */ - static const unsigned SalomeToFemusFaceIndex[6][6]; + static const unsigned SalomeToFemusFaceIndex[N_GEOM_ELS][6]; /** Determine mesh dimension from mesh file */ void FindDimension(hid_t gid, const std::string menu_name,hsize_t n_fem_type); From c6828e714fb7c1547592f3e6068d88be9568d458 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Wed, 25 Mar 2015 13:43:01 -0500 Subject: [PATCH 18/20] Found Tet10 salome connectivity --- src/mesh/SalomeIO.cpp | 23 ++++++++++---------- src/solution/Writer.cpp | 2 +- src/solution/Writer.hpp | 5 +++-- src/solution/XDMFWriter.cpp | 19 +++++++--------- src/solution/XDMFWriter.hpp | 2 +- unittests/testSalomeIO/input/OneTet10.med | Bin 0 -> 11961 bytes unittests/testSalomeIO/input/StudyTet10.hdf | Bin 0 -> 238217 bytes unittests/testSalomeIO/testSalomeIO.cpp | 4 ++-- 8 files changed, 26 insertions(+), 29 deletions(-) create mode 100644 unittests/testSalomeIO/input/OneTet10.med create mode 100644 unittests/testSalomeIO/input/StudyTet10.hdf diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 3e7b5b4a2..814a178d4 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -49,13 +49,13 @@ namespace femus { // / | / | // 0------16-------4 | // | 20 | 26 | 25 | -// | 2------18-|-----6 -// | / | / -// 11 / 24 15 / -// | 10 23 | 14 -// | / | / -// |/ |/ -// 3-------19------7 +// | 2------18-|-----6 zeta +// | / | / ^ +// 11 / 24 15 / | eta +// | 10 23 | 14 | / +// | / | / | / +// |/ |/ |/ +// 3-------19------7 -------> xi // TEMPLATE HEX27 (for future uses) // X------X--------X @@ -78,16 +78,15 @@ namespace femus { const unsigned SalomeIO::SalomeToFemusVertexIndex[N_GEOM_ELS][27]= { - {4,7,3,0,5,6,2,1,15,19,11,16,13,18,9,17,12,14,10,8,23,25,22,24,20,21,26}, //HEX27 - { - 0,4,1,6,5, - 2,7,8,9,3 - }, //TET10 + {4,7,3,0,5,6,2,1,15,19,11,16,13,18,9,17,12,14,10,8,23,25,22,24,20,21,26}, //HEX27 + {0,1,2,3,4,5,6,7,8,9}, //TET10 + { 3, 11,5, 9, 10,4, 12,17,14,15,16,13, 0, 8, 2, 6, 7, 1 }, //WEDGE18 + {0,1,2,3,4,5,6,7,8}, //QUAD9 {0,1,2,3,4,5}, //TRI6 {0,1,2} //EDGE3 diff --git a/src/solution/Writer.cpp b/src/solution/Writer.cpp index bccccfd99..1ac13b0d6 100644 --- a/src/solution/Writer.cpp +++ b/src/solution/Writer.cpp @@ -2,7 +2,7 @@ Program: FEMUS Module: Writer - Authors: Eugenio Aulisa, Simone Bnà + Authors: Eugenio Aulisa, Simone Bnà, Giorgio Bornia Copyright (c) FEMTTU All rights reserved. diff --git a/src/solution/Writer.hpp b/src/solution/Writer.hpp index 6e55b6961..cf2d69358 100644 --- a/src/solution/Writer.hpp +++ b/src/solution/Writer.hpp @@ -2,7 +2,7 @@ Program: FEMUS Module: Writer - Authors: Eugenio Aulisa, Simone Bnà + Authors: Eugenio Aulisa, Simone Bnà, Giorgio Bornia Copyright (c) FEMTTU All rights reserved. @@ -27,7 +27,8 @@ namespace femus { - // map from our connectivity to vtk-connectivity for paraview visualization //TODO move this to the appropriate place + // map from our connectivity to vtk-connectivity for paraview visualization + /// @todo move this to the appropriate place const unsigned map_pr[27] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,23,21,20,22,24,25,26}; //------------------------------------------------------------------------------ diff --git a/src/solution/XDMFWriter.cpp b/src/solution/XDMFWriter.cpp index 10271d2e2..be7b92068 100644 --- a/src/solution/XDMFWriter.cpp +++ b/src/solution/XDMFWriter.cpp @@ -42,10 +42,11 @@ namespace femus { - const std::string XDMFWriter::type_el[4][6] = {{"Hexahedron","Tetrahedron","Wedge","Quadrilateral","Triangle","Polyline"}, - {"Hexahedron_20","Tetrahedron_10","Not_implemented","Quadrilateral_8","Triangle_6","Edge_3"}, - {"Not_implemented","Not_implemented","Not_implemented","Not_implemented","Not_implemented","Not_implemented"}, - {"Hexahedron_27","Not_implemented","Not_implemented","Quadrilateral_9","Triangle_6","Edge_3"}}; + const std::string XDMFWriter::type_el[3][N_GEOM_ELS] = {{"Hexahedron","Tetrahedron","Wedge","Quadrilateral","Triangle","Polyline"}, //linear + {"Hexahedron_20","Tetrahedron_10","Not_implemented","Quadrilateral_8","Triangle_6","Edge_3"}, //serendipity + {"Hexahedron_27","Tetrahedron_10","Not_implemented","Quadrilateral_9","Triangle_6","Edge_3"}}; //tensor-product quadratic (some real, some fake) + /// @todo Tri6 and Tet10 are actually SERENDIPITY, not TENSOR-PRODUCT QUADRATIC. + // The corresponding tensor-product ones should be Tri7 and Tet14 const std::string XDMFWriter::_nodes_name = "/NODES"; const std::string XDMFWriter::_elems_name = "/ELEMS"; @@ -68,25 +69,21 @@ void XDMFWriter::write(const std::string output_path, const char order[], const print_all += !(vars[ivar].compare("All")) + !(vars[ivar].compare("all")) + !(vars[ivar].compare("ALL")); } - unsigned index=0; unsigned index_nd=0; if(!strcmp(order,"linear")) { //linear - index=0; index_nd=0; } else if(!strcmp(order,"quadratic")) { //quadratic - index=1; index_nd=1; } - else if(!strcmp(order,"biquadratic")) { //biquadratic - index=3; + else if(!strcmp(order,"biquadratic")) { //tensor-product quadratic (real and fake) index_nd=2; } /// @todo I assume that the mesh is not mixed std::string type_elem; unsigned elemtype = _ml_mesh->GetLevel(_gridn-1u)->el->GetElementType(ZERO_ELEM); - type_elem = XDMFWriter::type_el[index][elemtype]; + type_elem = XDMFWriter::type_el[index_nd][elemtype]; if (type_elem.compare("Not_implemented") == 0) { @@ -108,7 +105,7 @@ void XDMFWriter::write(const std::string output_path, const char order[], const nel+=_ml_mesh->GetLevel(_gridn-1u)->GetNumberOfElements(); unsigned icount; - unsigned el_dof_number = _ml_mesh->GetLevel(_gridn-1u)->el->GetElementDofNumber(0,index_nd); + unsigned el_dof_number = _ml_mesh->GetLevel(_gridn-1u)->el->GetElementDofNumber(ZERO_ELEM,index_nd); int * var_conn = new int [nel*el_dof_number]; std::vector< int > var_proc(nel); float *var_el_f = new float [nel]; diff --git a/src/solution/XDMFWriter.hpp b/src/solution/XDMFWriter.hpp index 819a018cb..ef61adb9c 100644 --- a/src/solution/XDMFWriter.hpp +++ b/src/solution/XDMFWriter.hpp @@ -146,7 +146,7 @@ class XDMFWriter : public Writer { private: - static const std::string type_el[4][6]; + static const std::string type_el[3][N_GEOM_ELS]; static const std::string _nodes_name; static const std::string _elems_name; diff --git a/unittests/testSalomeIO/input/OneTet10.med b/unittests/testSalomeIO/input/OneTet10.med new file mode 100644 index 0000000000000000000000000000000000000000..9962fe4417dc1c56221f80b598bd063eaa73c3cd GIT binary patch literal 11961 zcmeHNeQXp(6rb(cYp*?|twp6Ow9?Q*0ozbMj1su^_PE2l-Rs_+6#l7yK%vGG$b|$* z8ly%5Q3I$A3dRo-{!vlHj}Si^()y1eVoVg!MA0CUpcY8fCYm~LXWntUJGXmjuL{k* zWcTgOyqWj*z1jDEGwt@EKQN)Bs-&Q}m>>;vIx>f~H1dua>!fXJ(61F#KlxilBK_J_ zPysSH5P3-fkqB{D5y~cplz{$ow7LSm z*q##BLUaxMImPZhy!=72Nw31+3zpW;ZnRL7sIAS*hLcmAk3;s#x^KPp)w8c>>gvVWk{;7l|aK=qXGapS1&yXMVmi3k1EBC46LEwZYGedmk)Z$n;^j(T9VyU$bz(n1#9{=@+>s)IhK6Cek0kO){t!M+eS{L4Y}Ce z`ZV!?7Cz*{o-3z_KTYklW!?+q=CmQl|8Dq;w5K)fID2O3;-%gpXv))wJP?S*WP%G_ zqAP1PM1WNNH2?8H(BDEZq3Dw*PjqcfWoJ1Swd7RDJ}CizC}J-VUtygA^uP?o@X7e) z7`cfyfJyo{nd(U>achrWG-6uZq7^6A1vJ?~tD;7%bL;jbl#sPYpHykLYK3%?a)#0# zvX}(|U|OE?9=HZQFj`>LfR!sZ!05_T$^9cS=@!Tz-heL>3Ww#6m9nOOf`%;`rPuq{ zt^afcCS?JAm4r2S>c-yTVDc{4qKCxru~RCeSf`VsdLZ0Tu>Aq_)as@7YL5XxXUcCT zA#si~2u1G~XG)V$7BeaS3^UDUC8QEcNR$edS1;DV9wAFeb17-2S(%j+-4la-2GxqH z2@|zJsCB7TwO%*rjQi$%7S6CJz|9-@CdwE9zS(M3)m|PT@gjj4-kGS|O|~+2b)y!! zoA&C2FrNRMcj$?kYHRR5@&1A9R#f?`32eZJXATyL7ZH)9O6ojGlBV#vk-I91Byw~i z-GI7EiYw?{YNKO;1{ovbcQklfX|aX_wxb52jNyoKMLA@)Qi^ zi;edGz<(n*_7Y-lH;*^VXZnrvn0Y37)PwRUhrf|yd-fc+k+4gJzEA6n(}%E1i_0t8>-)rKL6z~e6r${ z%&T|A7uv6xDy8zk*mDyqF8h9HloHO9LQp@g919YoIN) z`^%g%G9E4?x2smWI1CPQEn-^@4i^Cl2);omBaj%wYPE2{)0rDUu~b$qSYb`JuW0gv z79qHIP%SsfsfjCg-O z)6TQJ2mWIZm~jH^=m0MOZood^*oL?PG9KUvz!QKiG7-*U#vwLE`}mz~vP?z$IL9U8 z1PVp_m#J(9YteqLnj2~=+V38@{DtF38`tK0xbD|_cl0?WKuq+=?TUkEIU2HFv0}x(P%eG5c^vts`NU)U9rFb}*nYc)t%K&%JHF;iBG2+3$a?@W1#rLyh&Ld~ z!UZ@4E@%f1xC8J8TzHlN=NIq{7zCbygB)NJGeIAWMf_reKf(=ca3=f_u4Db;+z$9- zZ9S8);*ZK1tjBz4@Z$Sb9>^!+Ir+Iqys2?J&!Ig7>o+*%W;_ZD&qBI zFinIbuZcMRTz>BJT>9p{aparTTYlV~4gP4H$<|KY)IZL$r~EzdfxHJ&=NXXc0AB!( RK#T!c0Wbs>PWTs^e*r%2vE~2( literal 0 HcmV?d00001 diff --git a/unittests/testSalomeIO/input/StudyTet10.hdf b/unittests/testSalomeIO/input/StudyTet10.hdf new file mode 100644 index 0000000000000000000000000000000000000000..8e04f37354847e515c4b8623726f96cbcdeae247 GIT binary patch literal 238217 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

-2X~Ouzo$owxly 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 aOS6V&rjO=k<|gqwrite(DEFAULT_OUTPUTDIR,"biquadratic"); From dac6ebac41d9ea03101882f7f8aa2243d7945870 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Wed, 25 Mar 2015 18:04:14 -0500 Subject: [PATCH 19/20] Cleaned SalomeIO and Writer --- src/enums/FETypeEnum.hpp | 2 -- src/mesh/SalomeIO.cpp | 13 ------------- src/solution/VTKWriter.cpp | 12 ++++++------ src/solution/Writer.cpp | 4 +++- src/solution/Writer.hpp | 6 ++---- src/solution/XDMFWriter.cpp | 10 +++++----- 6 files changed, 16 insertions(+), 31 deletions(-) diff --git a/src/enums/FETypeEnum.hpp b/src/enums/FETypeEnum.hpp index e95386c7e..76971ef97 100644 --- a/src/enums/FETypeEnum.hpp +++ b/src/enums/FETypeEnum.hpp @@ -8,9 +8,7 @@ enum FEType {QQ=0, LL, KK }; #define QL 3 #define BIQUADR_FE 2 -#define BIQUADR_TYPEEL 3 #define LINEAR_FE 0 -#define LINEAR_TYPEEL 0 #define NFE_FAMS 5 diff --git a/src/mesh/SalomeIO.cpp b/src/mesh/SalomeIO.cpp index 814a178d4..759bd69c0 100644 --- a/src/mesh/SalomeIO.cpp +++ b/src/mesh/SalomeIO.cpp @@ -277,19 +277,6 @@ void SalomeIO::read(const std::string& name, vector < vector < double> > &coords mesh.el->SetElementVertexIndex(iel,inode,conn_map[iel+i*n_elements]); } } - -// // // // // // // Adding Connectivity to mesh structure (Libmesh) -// // // // // mesh.reserve_elem(n_elements); -// // // // // // read the elements -// // // // // for(int iel=0; iel<(int)n_elements; ++iel) { -// // // // // // add the elements to the mesh -// // // // // Elem* elem = mesh.add_elem(Elem::build(eletype.type).release()); -// // // // // // add node pointers to the elements -// // // // // for(int i=0; iset_node(eletype.nodes[i])= mesh.node_ptr(conn_map[Node_el*iel+i]); -// // // // // elem->set_node(eletype.nodes[i])= mesh.node_ptr(conn_map[iel+i*n_elements]-1); -// // // // // } -// // // // // } // // end read ELEMENT/CELL **************** B diff --git a/src/solution/VTKWriter.cpp b/src/solution/VTKWriter.cpp index 6dc49290b..6ed8067e0 100644 --- a/src/solution/VTKWriter.cpp +++ b/src/solution/VTKWriter.cpp @@ -125,7 +125,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const short unsigned ielt = _ml_mesh->GetLevel(ig)->el->GetElementType(kel); for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(kel,index); j++) { counter++; - unsigned loc_vtk_conn = map_pr[j]; + unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetMeshDof(kel, loc_vtk_conn, index); unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode, index); if( jnodeMetis < offset_iprc ){ // check if jnodeMetis is a ghost node @@ -220,7 +220,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const if ( ig == _gridn-1u || 0 == _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(kel)) { short unsigned ielt=_ml_mesh->GetLevel(ig)->el->GetElementType(kel); for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(kel,index); j++) { - unsigned loc_vtk_conn = map_pr[j]; + unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetMeshDof(kel, loc_vtk_conn, index); unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode, index); if( jnodeMetis < offset_iprc ){ @@ -241,7 +241,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const if ( ig == _gridn-1u || 0 == _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(kel)) { short unsigned ielt=_ml_mesh->GetLevel(ig)->el->GetElementType(kel); for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(kel,index); j++) { - unsigned loc_vtk_conn = map_pr[j]; + unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetMeshDof(kel, loc_vtk_conn, index); unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode, index); if( jnodeMetis < offset_iprc ){ @@ -294,7 +294,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const unsigned kel = _ml_mesh->GetLevel(ig)->IS_Mts2Gmt_elem[iel]; if ( ig == _gridn-1u || 0 == _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(kel)) { for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(kel,index); j++) { - unsigned loc_vtk_conn = map_pr[j]; + unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetMeshDof(kel, loc_vtk_conn, index); unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode, index); var_conn[icount] = (jnodeMetis >= offset_iprc )? jnodeMetis - offset_iprc + offset_nvt : nvt0 + (ghost_counter++); @@ -566,7 +566,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const if ( ig == _gridn-1u || 0 == _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(kel)) { short unsigned ielt=_ml_mesh->GetLevel(ig)->el->GetElementType(kel); for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(kel,index); j++) { - unsigned loc_vtk_conn = map_pr[j]; + unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetMeshDof(kel, loc_vtk_conn, index); unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode, index); if( jnodeMetis < offset_iprc ){ @@ -802,7 +802,7 @@ void VTKWriter::Pwrite(const std::string output_path, const char order[], const // for (unsigned iel=0; iel<_ml_mesh->GetLevel(ig)->GetNumberOfElements(); iel++) { // if (ig==_gridn-1u || _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(iel)==0) { // for (unsigned j=0; j<_ml_mesh->GetLevel(ig)->el->GetElementDofNumber(iel,index); j++) { -// unsigned loc_vtk_conn = map_pr[j]; +// unsigned loc_vtk_conn = FemusToVTKorToXDMFConn[j]; // unsigned jnode=_ml_mesh->GetLevel(ig)->el->GetElementVertexIndex(iel,loc_vtk_conn)-1u; // unsigned jnodeMetis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode,index); // var_conn[icount] = offset_nvt + jnodeMetis; diff --git a/src/solution/Writer.cpp b/src/solution/Writer.cpp index 1ac13b0d6..1adb6ae2f 100644 --- a/src/solution/Writer.cpp +++ b/src/solution/Writer.cpp @@ -33,7 +33,9 @@ namespace femus { - + + const unsigned Writer::FemusToVTKorToXDMFConn[27] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,23,21,20,22,24,25,26}; + Writer::Writer( MultiLevelSolution* ml_sol ): _ml_sol(ml_sol), _ml_mesh(ml_sol->_ml_msh) { diff --git a/src/solution/Writer.hpp b/src/solution/Writer.hpp index cf2d69358..52e0eb774 100644 --- a/src/solution/Writer.hpp +++ b/src/solution/Writer.hpp @@ -27,10 +27,6 @@ namespace femus { - // map from our connectivity to vtk-connectivity for paraview visualization - /// @todo move this to the appropriate place - const unsigned map_pr[27] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,23,21,20,22,24,25,26}; - //------------------------------------------------------------------------------ // Forward declarations //------------------------------------------------------------------------------ @@ -83,6 +79,8 @@ namespace femus { int _gridr; + /** map from femus connectivity to vtk-connectivity for paraview visualization */ + static const unsigned FemusToVTKorToXDMFConn[27]; private: diff --git a/src/solution/XDMFWriter.cpp b/src/solution/XDMFWriter.cpp index be7b92068..1288d68a0 100644 --- a/src/solution/XDMFWriter.cpp +++ b/src/solution/XDMFWriter.cpp @@ -274,7 +274,7 @@ void XDMFWriter::write(const std::string output_path, const char order[], const if ( ig == _gridn-1u || _ml_mesh->GetLevel(ig)->el->GetRefinedElementIndex(iel) == 0) { int ndofs = _ml_mesh->GetLevel(ig)->el->GetElementDofNumber(iel,index_nd); for (unsigned j = 0; j < ndofs; j++) { - unsigned vtk_loc_conn = map_pr[j]; + unsigned vtk_loc_conn = FemusToVTKorToXDMFConn[j]; unsigned jnode = _ml_mesh->GetLevel(ig)->el->GetElementVertexIndex(iel,vtk_loc_conn)-1u; unsigned jnode_Metis = _ml_mesh->GetLevel(ig)->GetMetisDof(jnode,index_nd); var_conn[icount] = offset_conn + jnode_Metis; @@ -1484,9 +1484,9 @@ void XDMFWriter::PrintXDMFTopGeom(std::ofstream& out, #ifdef HAVE_HDF5 - uint n_children, order_typeel; - if (order_fe == BIQUADR_FE) { n_children = 1; order_typeel = BIQUADR_TYPEEL;} - else if (order_fe == LINEAR_FE) {n_children = NRE[mesh._eltype_flag[vb]]; order_typeel = LINEAR_TYPEEL;} + uint n_children; + if (order_fe == BIQUADR_FE) { n_children = 1; } + else if (order_fe == LINEAR_FE) {n_children = NRE[mesh._eltype_flag[vb]]; } else { std::cout << "Mesh Not supported" << std::endl; abort(); } uint nel = mesh._n_elements_vb_lev[vb][Level]; @@ -1495,7 +1495,7 @@ void XDMFWriter::PrintXDMFTopGeom(std::ofstream& out, std::ostringstream coord_lev; coord_lev << "_L" << Level; - PrintXDMFTopology(out,top_file.str(),hdf_field.str(), type_el[order_typeel][mesh._eltype_flag[vb]], nel*n_children, nel*n_children, NVE[mesh._eltype_flag[vb]][order_fe]); + PrintXDMFTopology(out,top_file.str(),hdf_field.str(), type_el[order_fe][mesh._eltype_flag[vb]], nel*n_children, nel*n_children, NVE[mesh._eltype_flag[vb]][order_fe]); PrintXDMFGeometry(out,geom_file.str(),_nodes_name+"/COORD/X",coord_lev.str(),"X_Y_Z","Float",mesh._NoNodesXLev[Level],1); From 068d485ba6d12cff0721e882bf3a1fd5a94fdc67 Mon Sep 17 00:00:00 2001 From: Giorgio Bornia Date: Wed, 25 Mar 2015 18:56:09 -0500 Subject: [PATCH 20/20] Removed _PP and _RR from LinearEquation --- src/algebra/LinearEquation.cpp | 10 ---------- src/algebra/LinearEquation.hpp | 2 +- src/equations/LinearImplicitSystem.cpp | 11 +++++++++++ src/equations/LinearImplicitSystem.hpp | 3 ++- src/meshGencase/GenCase.cpp | 24 ++++++++++++------------ src/meshGencase/GenCase.hpp | 8 ++++---- 6 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/algebra/LinearEquation.cpp b/src/algebra/LinearEquation.cpp index afaface63..fa402fc6c 100644 --- a/src/algebra/LinearEquation.cpp +++ b/src/algebra/LinearEquation.cpp @@ -42,8 +42,6 @@ LinearEquation::LinearEquation(Mesh *other_msh){ _EPSC = NULL; _RES = NULL; _RESC = NULL; - _PP = NULL; - _RR = NULL; _KK = NULL; _CC = NULL; } @@ -237,14 +235,6 @@ void LinearEquation::DeletePde() { delete _CC; } - - if (_msh->GetLevel()>0) { - if(_PP) - delete _PP; - if(_RR) - delete _RR; - } - if(_EPS) delete _EPS; diff --git a/src/algebra/LinearEquation.hpp b/src/algebra/LinearEquation.hpp index 50bc24a49..8576faad3 100644 --- a/src/algebra/LinearEquation.hpp +++ b/src/algebra/LinearEquation.hpp @@ -79,7 +79,7 @@ class LinearEquation : public ParallelObject { // member data Mesh *_msh; NumericVector *_EPS, *_EPSC, *_RES, *_RESC; - SparseMatrix *_KK, *_PP,*_RR, *_CC; + SparseMatrix *_KK, *_CC; vector < vector > KKoffset; vector < unsigned > KKghostsize; vector < vector < int> > KKghost_nd; diff --git a/src/equations/LinearImplicitSystem.cpp b/src/equations/LinearImplicitSystem.cpp index b3b5e4351..55bf29a6d 100644 --- a/src/equations/LinearImplicitSystem.cpp +++ b/src/equations/LinearImplicitSystem.cpp @@ -109,6 +109,8 @@ void LinearImplicitSystem::init() { AddVariableToBeSolved("All"); } + + /// @deprecated // this function is like init but it doesn't call InitPDE void LinearImplicitSystem::init_two() { @@ -124,6 +126,15 @@ void LinearImplicitSystem::init_two() { // _LinSolver[i]->InitPde(_SolSystemPdeIndex,_ml_sol->GetSolType(), // _ml_sol->GetSolName(),&_solution[i]->_Bdc,_gridr,_gridn,_SparsityPattern); // } + + + _PP.resize(_gridn); + _RR.resize(_gridn); + for(unsigned i=0;i<_gridn;i++){ + _PP[i]=NULL; + _RR[i]=NULL; + } + // // for (unsigned ig=1; ig<_gridn; ig++) { // BuildProlongatorMatrix(ig); diff --git a/src/equations/LinearImplicitSystem.hpp b/src/equations/LinearImplicitSystem.hpp index af5ea8fd5..9afea01f2 100644 --- a/src/equations/LinearImplicitSystem.hpp +++ b/src/equations/LinearImplicitSystem.hpp @@ -168,9 +168,10 @@ class LinearImplicitSystem : public ImplicitSystem { /** enforce sparcity pattern for setting uncoupled variables and save on memory allocation **/ void SetSparsityPattern(vector < bool > other_sparcity_pattern); + vector < SparseMatrix* > _PP, _RR; /// @todo put it back to protected + protected: - vector < SparseMatrix* > _PP, _RR; /** Create the Prolongator matrix for the Multigrid solver */ void Prolongator(const unsigned &gridf); diff --git a/src/meshGencase/GenCase.cpp b/src/meshGencase/GenCase.cpp index 60d437b17..9de00bc4e 100644 --- a/src/meshGencase/GenCase.cpp +++ b/src/meshGencase/GenCase.cpp @@ -2115,7 +2115,7 @@ void GenCase::ComputeMaxElXNode() { // ========================================= -void GenCase::ReadMGOps(const std::string output_path, const SystemTwo * mysys) { +void GenCase::ReadMGOps(const std::string output_path, SystemTwo * mysys) { std::string f_matrix = DEFAULT_F_MATRIX; std::string f_rest = DEFAULT_F_REST; @@ -2297,7 +2297,7 @@ void GenCase::ReadMGOps(const std::string output_path, const SystemTwo * mysys) // So, if the node_dof was not filled correctly, then when you -void GenCase::ReadMatrix(const std::string& namefile, const SystemTwo * mysys) { +void GenCase::ReadMatrix(const std::string& namefile, SystemTwo * mysys) { for (uint Level = 0; Level< mysys->GetGridn(); Level++) { @@ -2490,7 +2490,7 @@ void GenCase::ReadMatrix(const std::string& namefile, const SystemTwo * mysys) //============================= //This function depends on _iproc -void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { +void GenCase::ReadProl(const std::string& name, SystemTwo * mysys) { for (uint Level = 1; Level< mysys->GetGridn(); Level++) { @@ -2573,7 +2573,7 @@ void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { uint off_proc = mysys->GetMLProb().GetMeshTwo()._iproc*mysys->GetGridn(); - mysys->_LinSolver[Lev_f]->_PP = SparseMatrix::build().release(); + mysys->_PP[Lev_f] = SparseMatrix::build().release(); // // // _Prl[ Lev_f ]->init(0,0,0,0); //TODO BACK TO A REASONABLE INIT // local matrix dimension @@ -2650,7 +2650,7 @@ void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { std::cout << "Printing Prolongator ===========" << std::endl; pattern.print(); - mysys->_LinSolver[Lev_f]->_PP->update_sparsity_pattern_old(pattern); + mysys->_PP[Lev_f]->update_sparsity_pattern_old(pattern); //=========== VALUES =================== DenseMatrix *valmat; @@ -2670,7 +2670,7 @@ void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { for (uint j=0; j_LinSolver[Lev_f]->_PP->add_matrix(*valmat,tmp,ind); + mysys->_PP[Lev_f]->add_matrix(*valmat,tmp,ind); delete valmat; } } @@ -2691,7 +2691,7 @@ void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { pattern.clear(); - mysys->_LinSolver[Lev_f]->_PP->close(); + mysys->_PP[Lev_f]->close(); // if (mysys->GetMLProb().GetMeshTwo()._iproc==0) _Prl[ Lev_f ]->print_personal(); // _Prl[ Lev_f ]->print_graphic(false); //TODO should pass this true or false as a parameter } //end levels @@ -2727,7 +2727,7 @@ void GenCase::ReadProl(const std::string& name, const SystemTwo * mysys) { //AAA fai molta attenzione: per esplorare la node_dof devi usare Lev_c e Lev_f, //perche' sono legati ai DOF (devi pensare che la questione del mesh e' gia' risolta) -void GenCase::ReadRest(const std::string& name, const SystemTwo * mysys) { +void GenCase::ReadRest(const std::string& name, SystemTwo * mysys) { for (uint Level = 0; Level< mysys->GetGridn() - 1; Level++) { @@ -2809,7 +2809,7 @@ void GenCase::ReadRest(const std::string& name, const SystemTwo * mysys) { uint off_proc=mysys->GetGridn()*mysys->GetMLProb().GetMeshTwo()._iproc; - mysys->_LinSolver[Lev_c]->_RR = SparseMatrix::build().release(); + mysys->_RR[Lev_c] = SparseMatrix::build().release(); // // // _Rst[Lev_c]->init(0,0,0,0); //TODO BACK TO A REASONABLE INIT //we have to do this before appropriately!!! int nrowt=0;int nclnt=0; @@ -2873,7 +2873,7 @@ void GenCase::ReadRest(const std::string& name, const SystemTwo * mysys) { std::cout << "Printing Restrictor ===========" << std::endl; pattern.print(); - mysys->_LinSolver[Lev_c]->_RR->update_sparsity_pattern_old(pattern); //TODO see + mysys->_RR[Lev_c]->update_sparsity_pattern_old(pattern); //TODO see // _Rst[Lev_c]->close(); // if (mysys->GetMLProb().GetMeshTwo()._iproc==0) _Rst[Lev_c]->print_personal(); //there is no print function for rectangular matrices, and print_personal doesnt seem to be working... // la print stampa il contenuto, ma io voglio solo stampare lo sparsity pattern! @@ -2901,7 +2901,7 @@ void GenCase::ReadRest(const std::string& name, const SystemTwo * mysys) { for (uint i1=0;i1_bcond._bc[irow_top]*Rest_val[fe][ j+len[fe][i] ]; - mysys->_LinSolver[Lev_c]->_RR->add_matrix(*valmat,tmp,ind); + mysys->_RR[Lev_c]->add_matrix(*valmat,tmp,ind); delete valmat; }// end dof loop } // end var loop @@ -2921,7 +2921,7 @@ void GenCase::ReadRest(const std::string& name, const SystemTwo * mysys) { pattern.clear(); - mysys->_LinSolver[Lev_c]->_RR->close(); + mysys->_RR[Lev_c]->close(); // if (mysys->GetMLProb().GetMeshTwo()._iproc==0) _Rst[Lev_c]->print_personal(std::cout); // _Rst[Lev_c]->print_graphic(false); // TODO should pass this true or false as a parameter diff --git a/src/meshGencase/GenCase.hpp b/src/meshGencase/GenCase.hpp index d7ba36da4..157bf9f21 100644 --- a/src/meshGencase/GenCase.hpp +++ b/src/meshGencase/GenCase.hpp @@ -47,10 +47,10 @@ class GenCase : public MultiLevelMeshTwo { void ComputeAndPrintProl(const std::string output_path); void ComputeAndPrintRest(const std::string output_path); - static void ReadMGOps(const std::string output_path, const SystemTwo * mysys); - static void ReadMatrix(const std::string& name, const SystemTwo * mysys); - static void ReadProl(const std::string& name, const SystemTwo * mysys); - static void ReadRest(const std::string& name, const SystemTwo * mysys); + static void ReadMGOps(const std::string output_path, SystemTwo * mysys); + static void ReadMatrix(const std::string& name, SystemTwo * mysys); + static void ReadProl(const std::string& name, SystemTwo * mysys); + static void ReadRest(const std::string& name, SystemTwo * mysys); void CreateMeshStructuresLevSubd(const std::string output_path); void Delete();