diff --git a/Geo/MElementCut.cpp b/Geo/MElementCut.cpp index 667d49dae25df24f22b2eddf16a80e64686eeaed..809a3885bfd25b1d652d45304765273a4ddb4a49 100644 --- a/Geo/MElementCut.cpp +++ b/Geo/MElementCut.cpp @@ -520,7 +520,7 @@ static void elementCutMesh(MElement *e, std::vector<const gLevelset *> &RPN, MElement *copy = factory.create(eType, vmv, ++numEle, ePart); double **nodeLs = new double*[e->getNumPrimaryVertices()]; - for(int i = 0; i < e->getNumPrimaryVertices(); i++) nodeLs[i] = new double[verticesLs.size2()]; + // for(int i = 0; i < e->getNumPrimaryVertices(); i++) nodeLs[i] = new double[verticesLs.size2()]; switch (eType) { case MSH_TET_4 : @@ -534,7 +534,10 @@ static void elementCutMesh(MElement *e, std::vector<const gLevelset *> &RPN, e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z(), e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z(), e->getVertex(3)->x(), e->getVertex(3)->y(), e->getVertex(3)->z()); - for(int i = 0; i < 4; i++) nodeLs[i] = &verticesLs(e->getVertex(i)->getIndex(),0); + for(int i = 0; i < 4; i++) { + nodeLs[i] = &verticesLs(e->getVertex(i)->getIndex(),0); + //for(int j = 0; j < verticesLs.size2(); j++)nodeLs(i,j) = verticesLs[j]; + } isCut = T.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder, tetras, quads, triangles, 0, nodeLs); } diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h index 18d0efef5faedf1ff334c6e59802924f13d38157..4fe957c33d55f753f0c4718642a56924679b3d8c 100644 --- a/Numeric/fullMatrix.h +++ b/Numeric/fullMatrix.h @@ -135,6 +135,12 @@ class fullMatrix } int gemm(lua_State *L); #endif // HAVE LUA + fullMatrix(scalar *original, int r, int c){ + _r = r; + _c = c; + _own_data = false; + _data = original; + } fullMatrix(fullMatrix<scalar> &original, int c_start, int c){ _c = c; _r = original._r; diff --git a/Post/PView.cpp b/Post/PView.cpp index 8f59d995badd2c3301e26709534c7abc7cc5ab4f..7595047c5b6f23dc280320ce18aaddf24c44fb30 100644 --- a/Post/PView.cpp +++ b/Post/PView.cpp @@ -112,7 +112,7 @@ PView::PView(std::string xname, std::string yname, PView::PView(std::string name, std::string type, GModel *model, std::map<int, std::vector<double> > &data, - double time) + double time, int numC) { _init(); PViewDataGModel::DataType t; @@ -127,7 +127,7 @@ PView::PView(std::string name, std::string type, return; } PViewDataGModel *d = new PViewDataGModel(t); - d->addData(model, data, 0, time, 1); + d->addData(model, data, 0, time, 1, numC); d->setName(name); d->setFileName(name + ".msh"); _data = d; @@ -138,10 +138,10 @@ PView::PView(std::string name, std::string type, } void PView::addStep(GModel *model, std::map<int, std::vector<double> > &data, - double time) + double time, int numC) { PViewDataGModel *d = dynamic_cast<PViewDataGModel*>(_data); - if(d) d->addData(model, data, d->getNumTimeSteps(), time, 1); + if(d) d->addData(model, data, d->getNumTimeSteps(), time, 1, numC); else Msg::Error("Can only add step data to model-based datasets"); } diff --git a/Post/PView.h b/Post/PView.h index d621a93e4e1b6d6ddc815739da0f303db652a45d..04d8727acd6953072d10d6979d58ddc6274012d9 100644 --- a/Post/PView.h +++ b/Post/PView.h @@ -52,10 +52,11 @@ class PView{ std::vector<double> &x, std::vector<double> &y); // construct a new model-based view from a bunch of data PView(std::string name, std::string type, GModel *model, - std::map<int, std::vector<double> > &data, double time=0.); + std::map<int, std::vector<double> > &data, double time=0., + int numComp = -1); // add a new time step to a given model-based view void addStep(GModel *model, std::map<int, std::vector<double> > &data, - double time=0.); + double time=0.,int numComp = -1); // default destructor ~PView(); diff --git a/Post/PViewDataGModel.h b/Post/PViewDataGModel.h index 9a5cf29edf2b58f68e090f9c8de8f7a10a2221b1..2cc0c60fc3410d0b385241bc3e0703049d7d0d37 100644 --- a/Post/PViewDataGModel.h +++ b/Post/PViewDataGModel.h @@ -185,7 +185,7 @@ class PViewDataGModel : public PViewData { // node or element number depending on the type of dataset; all the // vectors are supposed to have the same length) bool addData(GModel *model, std::map<int, std::vector<double> > &data, - int step, double time, int partition); + int step, double time, int partition, int numC); // I/O routines bool readMSH(std::string fileName, int fileIndex, FILE *fp, bool binary, diff --git a/Post/PViewDataGModelIO.cpp b/Post/PViewDataGModelIO.cpp index 6979d617c9e18e450c589afcde5a04f170902f8e..60bfa2c41ec216e1a33e4d2aa19b63dbad8c59c0 100644 --- a/Post/PViewDataGModelIO.cpp +++ b/Post/PViewDataGModelIO.cpp @@ -12,14 +12,17 @@ #include "StringUtils.h" bool PViewDataGModel::addData(GModel *model, std::map<int, std::vector<double> > &data, - int step, double time, int partition) + int step, double time, int partition, int numC) { if(data.empty()) return false; int numComp = 9; - for(std::map<int, std::vector<double> >::iterator it = data.begin(); - it != data.end(); it++) - numComp = std::min(numComp, (int)it->second.size()); + if (numC < 0){ + for(std::map<int, std::vector<double> >::iterator it = data.begin(); + it != data.end(); it++) + numComp = std::min(numComp, (int)it->second.size()); + } + else numComp = numC; while(step >= (int)_steps.size()) _steps.push_back(new stepData<double>(model, numComp)); diff --git a/Solver/CMakeLists.txt b/Solver/CMakeLists.txt index 60898af6e31f95eb5e2e0deb4f1e2c8e654ea68a..b230ce42754bb5722167e645c96d87eb117c0c5f 100644 --- a/Solver/CMakeLists.txt +++ b/Solver/CMakeLists.txt @@ -20,6 +20,7 @@ set(SRC dgConservationLawWaveEquation.cpp function.cpp functionDerivator.cpp + luaFunction.cpp ) file(GLOB HDR RELATIVE ${CMAKE_SOURCE_DIR}/Solver *.h) diff --git a/Solver/dgAlgorithm.cpp b/Solver/dgAlgorithm.cpp index 9d24b827039ae1a8c7829590ab51b6e9d88251b3..0203bcf63ad39d616755ab5258b3600845fdc2fd 100644 --- a/Solver/dgAlgorithm.cpp +++ b/Solver/dgAlgorithm.cpp @@ -17,7 +17,7 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe const dgGroupOfElements & group, const fullMatrix<double> &solution, fullMatrix<double> &residual // the residual - ) + ) { // ----- 1 ---- get the solution at quadrature points // ----- 1.1 --- allocate a matrix of size (nbFields * nbElements, nbQuadraturePoints) @@ -114,7 +114,8 @@ void dgAlgorithm::residualVolume ( //dofManager &dof, // the DOF manager (maybe } if(sourceTerm){ residual.gemm(group.getSourceRedistributionMatrix(),Source); - delete sourceTerm; + // FIXME (JF) : for now TEST TEST + // delete sourceTerm; } } @@ -232,49 +233,52 @@ void dgAlgorithm::multAddInverseMassMatrix ( /*dofManager &dof,*/ } } - void dgAlgorithm::rungeKutta ( - const dgConservationLaw &claw, // conservation law - std::vector<dgGroupOfElements*> &eGroups, // group of elements - std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs - std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries - double h, // time-step - fullMatrix<double> &residu, - fullMatrix<double> &sol, - int orderRK) // order of RK integrator -{ + + void dgAlgorithm::rungeKutta (const dgConservationLaw &claw, // conservation law + std::vector<dgGroupOfElements*> &eGroups, // group of elements + std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs + std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries + double h, // time-step + std::vector<fullMatrix<double> *> &residu, + std::vector<fullMatrix<double> *> &sol, + int orderRK) // order of RK integrator + { // U_{n+1}=U_n+h*(SUM_i a_i*K_i) // K_i=M^(-1)R(U_n+b_i*K_{i-1}) - double a[4] = {h/6.0,h/3.0,h/3.0,h/6.0}; - double b[4] = {0.,h/2.0,h/2.0,h}; - - fullMatrix<double> K(sol); - // Current updated solution - fullMatrix<double> Unp(sol); - fullMatrix<double> residuEl, KEl; - fullMatrix<double> iMassEl; - - int nbNodes = eGroups[0]->getNbNodes(); - int nbFields = sol.size2()/eGroups[0]->getNbElements(); - - for(int j=0; j<orderRK;j++){ - if(j!=0){ - K.scale(b[j]); - K.add(sol); - } - this->residual(claw,eGroups,fGroups,bGroups,K,residu); - K.scale(0.); - for(int i=0;i<eGroups[0]->getNbElements();i++) { - residuEl.setAsProxy(residu,i*nbFields,nbFields); - KEl.setAsProxy(K,i*nbFields,nbFields); - iMassEl.setAsProxy(eGroups[0]->getInverseMassMatrix(),i*nbNodes,nbNodes); - iMassEl.mult(residuEl,KEl); - } - Unp.add(K,a[j]); - } - sol=Unp; -} + /* + double a[4] = {h/6.0,h/3.0,h/3.0,h/6.0}; + double b[4] = {0.,h/2.0,h/2.0,h}; + + fullMatrix<double> K(sol); + // Current updated solution + fullMatrix<double> Unp(sol); + fullMatrix<double> residuEl, KEl; + fullMatrix<double> iMassEl; + + int nbNodes = eGroups[0]->getNbNodes(); + int nbFields = sol.size2()/eGroups[0]->getNbElements(); + + for(int j=0; j<orderRK;j++){ + if(j!=0){ + K.scale(b[j]); + K.add(sol); + } + this->residual(claw,eGroups,fGroups,bGroups,K,residu); + K.scale(0.); + for(int i=0;i<eGroups[0]->getNbElements();i++) { + residuEl.setAsProxy(residu,i*nbFields,nbFields); + KEl.setAsProxy(K,i*nbFields,nbFields); + iMassEl.setAsProxy(eGroups[0]->getInverseMassMatrix(),i*nbNodes,nbNodes); + iMassEl.mult(residuEl,KEl); + } + Unp.add(K,a[j]); + } + sol=Unp; + } + */ + } void dgAlgorithm::residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here) const dgConservationLaw &claw, // the conservation law @@ -386,37 +390,47 @@ void dgAlgorithm::buildGroups(GModel *model, int dim, int order, } } -// works only if there is only 1 group of element +// works for any number of groups void dgAlgorithm::residual( const dgConservationLaw &claw, - std::vector<dgGroupOfElements*> &eGroups, //group of elements - std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs - std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries - fullMatrix<double> &solution, // solution - fullMatrix<double> &residu) // residual + std::vector<dgGroupOfElements*> &eGroups, //group of elements + std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs + std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries + std::vector<fullMatrix<double> *> &solution, // solution + std::vector<fullMatrix<double> *> &residu) // residual { int nbFields=claw.nbFields(); - dgAlgorithm algo; - residu.scale(0); //volume term for(size_t i=0;i<eGroups.size() ; i++) { - algo.residualVolume(claw,*eGroups[i],solution,residu); + residu[i]->scale(0); + residualVolume(claw,*eGroups[i],*solution[i],*residu[i]); } //interface term for(size_t i=0;i<fGroups.size() ; i++) { dgGroupOfFaces &faces = *fGroups[i]; + int iGroupLeft = -1, iGroupRight = -1; + for(size_t j=0;j<eGroups.size() ; j++) { + if (eGroups[i] == &faces.getGroupLeft())iGroupLeft = j; + if (eGroups[i] == &faces.getGroupRight())iGroupRight= j; + } + fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*2*nbFields); fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*2*nbFields); - faces.mapToInterface(nbFields, solution, solution, solInterface); - algo.residualInterface(claw,faces,solInterface,solution,solution,residuInterface); - faces.mapFromInterface(nbFields, residuInterface, residu, residu); + faces.mapToInterface(nbFields, *solution[iGroupLeft], *solution[iGroupRight], solInterface); + residualInterface(claw,faces,solInterface,*solution[iGroupLeft], *solution[iGroupRight],residuInterface); + faces.mapFromInterface(nbFields, residuInterface, *residu[iGroupLeft], *residu[iGroupLeft]); } //boundaries for(size_t i=0;i<bGroups.size() ; i++) { dgGroupOfFaces &faces = *bGroups[i]; + int iGroupLeft = -1, iGroupRight = -1; + for(size_t j=0;j<eGroups.size() ; j++) { + if (eGroups[i] == &faces.getGroupLeft())iGroupLeft = j; + if (eGroups[i] == &faces.getGroupRight())iGroupRight= j; + } fullMatrix<double> solInterface(faces.getNbNodes(),faces.getNbElements()*nbFields); fullMatrix<double> residuInterface(faces.getNbNodes(),faces.getNbElements()*nbFields); - faces.mapToInterface(nbFields, solution, solution, solInterface); - algo.residualBoundary(claw,faces,solInterface,solution,residuInterface); - faces.mapFromInterface(nbFields, residuInterface, residu, residu); + faces.mapToInterface(nbFields, *solution[iGroupLeft], *solution[iGroupRight], solInterface); + residualBoundary(claw,faces,solInterface,*solution[iGroupLeft],residuInterface); + faces.mapFromInterface(nbFields, residuInterface, *residu[iGroupLeft], *residu[iGroupRight]); } } diff --git a/Solver/dgAlgorithm.h b/Solver/dgAlgorithm.h index f51f050e423634c154b1258b472f86b835b0a0ef..dfad3132e488ba949dd3a9674a8e4c4e08e69ca1 100644 --- a/Solver/dgAlgorithm.h +++ b/Solver/dgAlgorithm.h @@ -11,50 +11,50 @@ class dgTerm; class dgAlgorithm { public : - static void residualVolume ( //dofManager &dof, // the DOF manager (maybe useless here) - const dgConservationLaw &claw, // the conservation law - const dgGroupOfElements & group, - const fullMatrix<double> &solution, - fullMatrix<double> &residual); - static void residualInterface ( //dofManager &dof, // the DOF manager (maybe useless here) - const dgConservationLaw &claw, // the conservation law - const dgGroupOfFaces & group, - const fullMatrix<double> &solution, // ! at face nodes - fullMatrix<double> &solutionRight, - fullMatrix<double> &solutionLeft, - fullMatrix<double> &residual); // ! at face nodes - static void residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here) - const dgConservationLaw &claw, // the conservation law - const dgGroupOfFaces &group, - const fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &solutionLeft, - fullMatrix<double> &residual // residual !! at faces nodes - ); - // works only if there is only 1 group of element + static void residualVolume ( //dofManager &dof, // the DOF manager (maybe useless here) + const dgConservationLaw &claw, // the conservation law + const dgGroupOfElements & group, + const fullMatrix<double> &solution, + fullMatrix<double> &residual); + static void residualInterface ( //dofManager &dof, // the DOF manager (maybe useless here) + const dgConservationLaw &claw, // the conservation law + const dgGroupOfFaces & group, + const fullMatrix<double> &solution, // ! at face nodes + fullMatrix<double> &solutionRight, + fullMatrix<double> &solutionLeft, + fullMatrix<double> &residual); // ! at face nodes + static void residualBoundary ( //dofManager &dof, // the DOF manager (maybe useless here) + const dgConservationLaw &claw, // the conservation law + const dgGroupOfFaces &group, + const fullMatrix<double> &solution, // solution !! at faces nodes + fullMatrix<double> &solutionLeft, + fullMatrix<double> &residual // residual !! at faces nodes + ); + // works only if there is only 1 group of element static void residual( const dgConservationLaw &claw, - std::vector<dgGroupOfElements*> &eGroups, //group of elements - std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs - std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries - fullMatrix<double> &solution, // solution !! at faces nodes - fullMatrix<double> &residual // residual !! at faces nodes - ); + std::vector<dgGroupOfElements*> &eGroups, //group of elements + std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs + std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries + std::vector<fullMatrix<double> *> &solution, // solution !! at faces nodes + std::vector<fullMatrix<double> *> &residual // residual !! at faces nodes + ); void rungeKutta ( - const dgConservationLaw &claw, - std::vector<dgGroupOfElements*> &eGroups, //group of elements - std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs - std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries - double h, - fullMatrix<double> &residu, - fullMatrix<double> &sol, - int orderRK=4); + const dgConservationLaw &claw, + std::vector<dgGroupOfElements*> &eGroups, //group of elements + std::vector<dgGroupOfFaces*> &fGroups, // group of interfacs + std::vector<dgGroupOfFaces*> &bGroups, // group of boundaries + double h, + std::vector<fullMatrix<double> *> &residu, + std::vector<fullMatrix<double> *> &sol, + int orderRK=4); static void multAddInverseMassMatrix ( /*dofManager &dof,*/ - const dgGroupOfElements & group, - fullMatrix<double> &residu, - fullMatrix<double> &sol); + const dgGroupOfElements & group, + fullMatrix<double> &residu, + fullMatrix<double> &sol); static void buildGroups(GModel *model, int dim, int order, - std::vector<dgGroupOfElements*> &eGroups, - std::vector<dgGroupOfFaces*> &fGroups, - std::vector<dgGroupOfFaces*> &bGroups); + std::vector<dgGroupOfElements*> &eGroups, + std::vector<dgGroupOfFaces*> &fGroups, + std::vector<dgGroupOfFaces*> &bGroups); }; diff --git a/Solver/dgMainLua.cpp b/Solver/dgMainLua.cpp index 487487f38c36ab07a62f64c1d42aa6f84815c33e..cb0ac1845b3172ecdb43fa79ba7a119aee64dbe2 100644 --- a/Solver/dgMainLua.cpp +++ b/Solver/dgMainLua.cpp @@ -2,8 +2,8 @@ #include "Gmsh.h" #include "LuaBindings_Geo.h" #include "dgSystemOfEquations.h" +#include "luaFunction.h" #include "function.h" - void report_errors(lua_State *L, int status) { if ( status!=0 ) { @@ -28,6 +28,7 @@ int main(int argc, char *argv[]) dgSystemOfEquations::Register(L); fullMatrix<double>::Register(L); function::registerDefaultFunctions(); + RegisterFunctions(L); int s = luaL_loadfile(L, argv[1]); diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp index 4faccae24e068cf76a2d749249e5551596abd1fe..6cc5af311124f95cf17de611f4f7a66a5cb24db8 100644 --- a/Solver/dgSystemOfEquations.cpp +++ b/Solver/dgSystemOfEquations.cpp @@ -1,5 +1,11 @@ +#include <stdio.h> +#include <stdlib.h> #include "dgSystemOfEquations.h" #include "LuaBindings_Geo.h" +#include "function.h" +#include "MElement.h" +#include "PView.h" +#include "PViewData.h" #if defined(HAVE_LUA) // define the name of the object that will be used in Lua @@ -15,6 +21,7 @@ Luna<dgSystemOfEquations>::RegType dgSystemOfEquations::methods[] = { _method(dgSystemOfEquations, setOrder), _method(dgSystemOfEquations, setup), _method(dgSystemOfEquations, addBoundaryCondition), + _method(dgSystemOfEquations, L2Projection), {0,0} }; @@ -24,6 +31,22 @@ void dgSystemOfEquations::Register (lua_State *L){ Luna<dgSystemOfEquations>::Register(L); } +class dgConservationLawL2Projection : public dgConservationLaw { + std::string _functionName; +public: + dgConservationLawL2Projection(const std::string & functionName, + dgConservationLaw &_claw) : + _functionName(functionName) + { + _nbf =_claw.nbFields(); + } + dataCacheDouble *newSourceTerm(dataCacheMap &cacheMap)const { + //return new gaussian(cacheMap,0.2,0.3); + return &cacheMap.get(_functionName); + } +}; + + // system of equations is build using a mesh dgSystemOfEquations::dgSystemOfEquations(lua_State *L){ // get the number of arguments @@ -71,6 +94,14 @@ int dgSystemOfEquations::addBoundaryCondition (lua_State *L){ else throw; } +// do a L2 projection +int dgSystemOfEquations::L2Projection (lua_State *L){ + dgConservationLawL2Projection Law(std::string(luaL_checkstring(L, 1)),*_claw); + for (int i=0;i<_elementGroups.size();i++){ + _algo->residualVolume(Law,*_elementGroups[i],*_solutionProxys[i],*_rightHandSideProxys[i]); + _algo->multAddInverseMassMatrix(*_elementGroups[i],*_rightHandSideProxys[i],*_solutionProxys[i]); + } +} // ok, we can setup the groups and create solution vectors int dgSystemOfEquations::setup(lua_State *L){ @@ -81,13 +112,28 @@ int dgSystemOfEquations::setup(lua_State *L){ _elementGroups, _faceGroups, _boundaryGroups); - //for now, we suppose there is only one group of elements - int nbNodes = _elementGroups[0]->getNbNodes(); - int nbElements = _elementGroups[0]->getNbElements(); - // allocate solution and RHS + // compute the total size of the soution + _dataSize = 0; int nbFields = _claw->nbFields(); - _solution = new fullMatrix<double> (nbNodes,nbFields*nbElements); - _rightHandSide = new fullMatrix<double> (nbNodes,nbFields*nbElements); + for (int i=0;i<_elementGroups.size();i++){ + int nbNodes = _elementGroups[i]->getNbNodes(); + int nbElements = _elementGroups[i]->getNbElements(); + _dataSize += nbNodes*nbFields*nbElements; + } + // allocate the big vectors + _solution = new double [_dataSize]; + _rightHandSide = new double [_dataSize]; + // create proxys for each group + int offset = 0; + _solutionProxys.resize(_elementGroups.size()); + _rightHandSideProxys.resize(_elementGroups.size()); + for (int i=0;i<_elementGroups.size();i++){ + int nbNodes = _elementGroups[i]->getNbNodes(); + int nbElements = _elementGroups[i]->getNbElements(); + _solutionProxys[i] = new fullMatrix<double> (&_solution[offset*sizeof(double)],nbNodes, nbFields*nbElements); + _rightHandSideProxys[i] = new fullMatrix<double> (&_rightHandSide[offset*sizeof(double)],nbNodes, nbFields*nbElements); + offset += nbNodes*nbFields*nbElements; + } } @@ -97,7 +143,7 @@ int dgSystemOfEquations::getSolution(lua_State *L){ } int dgSystemOfEquations::computeRHS(lua_State *L){ - _algo->residual(*_claw, _elementGroups, _faceGroups, _boundaryGroups, *_solution, *_rightHandSide); + _algo->residual(*_claw, _elementGroups, _faceGroups, _boundaryGroups, _solutionProxys, _rightHandSideProxys); lua_pushlightuserdata (L, _solution); return 1; } @@ -108,35 +154,78 @@ int dgSystemOfEquations::getRHS(lua_State *L){ } int dgSystemOfEquations::exportSolution(lua_State *L){ + std::string outputFile(luaL_checkstring(L, 1)); + export_solution_as_is(outputFile); } #endif // HAVE_LUA -dgSystemOfEquations::dgSystemOfEquations(GModel *obj, dgConservationLaw *claw,int order){ - setup(obj,claw,order); -} - dgSystemOfEquations::~dgSystemOfEquations(){ - delete _solution; - delete _rightHandSide; + for (int i=0;i<_elementGroups.size();i++){ + delete _solutionProxys[i]; + delete _rightHandSideProxys[i]; + delete _elementGroups[i]; + } + delete [] _solution; + delete [] _rightHandSide; } -void dgSystemOfEquations::setup(GModel *obj, dgConservationLaw *claw, int order){ - _gm = obj; - _claw = claw; - _algo = new dgAlgorithm; - _order= order; - _dimension = _gm->getNumRegions() ? 3 : 2; - _algo->buildGroups(_gm, - _dimension, - _order, - _elementGroups, - _faceGroups, - _boundaryGroups); - //for now, we suppose there is only one group of elements - int nbNodes = _elementGroups[0]->getNbNodes(); - int nbElements = _elementGroups[0]->getNbElements(); - // allocate solution and RHS - int nbFields = _claw->nbFields(); - _solution = new fullMatrix<double> (nbNodes,nbFields*nbElements); - _rightHandSide = new fullMatrix<double> (nbNodes,nbFields*nbElements); +void dgSystemOfEquations::export_solution_as_is (const std::string &name){ + // the elementnodedata::export does not work !! + + for (int ICOMP = 0; ICOMP<_claw->nbFields();++ICOMP){ + char aaa[245]; + sprintf(aaa,"%s_COMP_%d.msh",name.c_str(),ICOMP); + FILE *f = fopen (aaa,"w"); + int COUNT = 0; + for (int i=0;i < _elementGroups.size() ;i++){ + COUNT += _elementGroups[i]->getNbElements(); + } + fprintf(f,"$MeshFormat\n2.1 0 8\n$EndMeshFormat\n"); + fprintf(f,"$ElementNodeData\n"); + fprintf(f,"1\n"); + fprintf(f,"\"%s\"\n",name.c_str()); + fprintf(f,"1\n"); + fprintf(f,"0.0\n"); + fprintf(f,"3\n"); + fprintf(f,"0\n 1\n %d\n",COUNT); + for (int i=0;i < _elementGroups.size() ;i++){ + for (int iElement=0 ; iElement<_elementGroups[i]->getNbElements() ;++iElement) { + MElement *e = _elementGroups[i]->getElement(iElement); + int num = e->getNum(); + fullMatrix<double> sol = getSolutionProxy (i, iElement); + fprintf(f,"%d %d",num,sol.size1()); + for (int k=0;k<sol.size1();++k) { + fprintf(f,"%12.5E ",sol(k,ICOMP)); + } + fprintf(f,"\n"); + } + } + fprintf(f,"$EndElementNodeData\n"); + fclose(f); + } + return; + // we should discuss that : we do a copy of the solution, this should + // be avoided ! + + std::map<int, std::vector<double> > data; + + for (int i=0;i < _elementGroups.size() ;i++){ + for (int iElement=0 ; iElement<_elementGroups[i]->getNbElements() ;++iElement) { + MElement *e = _elementGroups[i]->getElement(iElement); + int num = e->getNum(); + fullMatrix<double> sol = getSolutionProxy (i, iElement); + std::vector<double> val; + // val.resize(sol.size2()*sol.size1()); + val.resize(sol.size1()); + int counter = 0; + // for (int iC=0;iC<sol.size2();iC++) + printf("%g %g %g\n",sol(0,0),sol(1,0),sol(2,0)); + for (int iR=0;iR<sol.size1();iR++)val[counter++] = sol(iR,0); + data[num] = val; + } + } + + PView *pv = new PView (name, "ElementNodeData", _gm, data, 0.0, 1); + pv->getData()->writeMSH(name+".msh", false); + delete pv; } diff --git a/Solver/dgSystemOfEquations.h b/Solver/dgSystemOfEquations.h index 879a6998b28c93e63064b221b6ebba6c681bdf52..567f37f5b90518b093623538b26bb4131da10b43 100644 --- a/Solver/dgSystemOfEquations.h +++ b/Solver/dgSystemOfEquations.h @@ -31,18 +31,19 @@ class dgSystemOfEquations { int _order; // dimension of the problem int _dimension; - // the solution - fullMatrix<double> *_solution; - // the right hand side (a temporary vector) - fullMatrix<double> *_rightHandSide; + // solution and righ hand sides as a large arrays of doubles + int _dataSize; + double * _solution; + double * _rightHandSide; + // proxis of the solution and of the right hand side for each group; + std::vector<fullMatrix<double> *> _solutionProxys; + std::vector<fullMatrix<double> *> _rightHandSideProxys; // groups of elements (volume terms) std::vector<dgGroupOfElements*> _elementGroups; // groups of faces (interface terms) std::vector<dgGroupOfFaces*> _faceGroups; // groups of faces (boundary conditions) std::vector<dgGroupOfFaces*> _boundaryGroups; - // sets up everything - void setup(GModel *gm, dgConservationLaw *claw, int order); dgSystemOfEquations(const dgSystemOfEquations &) {} public: // lua stuff @@ -58,11 +59,15 @@ public: int setConservationLaw (lua_State *L); // set the conservationLaw int addBoundaryCondition (lua_State *L); // add a boundary condition : "physical name", "type", [options] int setup (lua_State *L); // setup the groups and allocate + int L2Projection (lua_State *L); // assign the solution to a given function dgSystemOfEquations(lua_State *L); #endif // HAVE LUA - dgSystemOfEquations(GModel *gm, dgConservationLaw *claw, int order); + inline const fullMatrix<double> getSolutionProxy (int iGroup, int iElement){ + return fullMatrix<double> ( *_solutionProxys [iGroup] , + iElement * _claw->nbFields(),_claw->nbFields()); + } + void export_solution_as_is (const std::string &fileName); ~dgSystemOfEquations(); - private: }; diff --git a/Solver/luaFunction.cpp b/Solver/luaFunction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..74cde201e6848db93c4dde431028165f71154d1c --- /dev/null +++ b/Solver/luaFunction.cpp @@ -0,0 +1,100 @@ +#include "luaFunction.h" +#if defined(HAVE_LUA) +#include <string> +#include <vector> +#include "function.h" +// function that is defined in Lua + +class functionLua : public function { + lua_State *_L; + std::string _luaFunctionName; + std::vector<std::string> _dependenciesName; + int _nbCol; + private: + class data : public dataCacheDouble{ + private: + dataCacheDouble &_uvw; + const functionLua *_function; + std::vector<dataCacheDouble *> _dependencies; + public: + data(const functionLua *f, dataCacheMap *m) + : _function(f),_uvw(m->get("UVW",this)) + { + _dependencies.resize ( _function->_dependenciesName.size()); + for (int i=0;i<_function->_dependenciesName.size();i++) + _dependencies[i] = &m->get(_function->_dependenciesName[i],this); + } + void _eval() + { + if(_value.size1()!=_uvw().size1() || _value.size2() != _function->_nbCol){ + _value=fullMatrix<double>(_uvw().size1(),_function->_nbCol); + } + lua_getfield(_function->_L, LUA_GLOBALSINDEX, _function->_luaFunctionName.c_str()); + for (int i=0;i< _dependencies.size();i++){ + const fullMatrix<double> *data = &(*_dependencies[i])(); + lua_pushlightuserdata (_function->_L, (void*) data); + } + lua_pushlightuserdata (_function->_L, &_value); + lua_call(_function->_L,_dependencies.size()+1,0); /* call Lua function */ + } + }; + public: + functionLua (int nbCol, + std::string &luaFunctionName, + std::vector<std::string> &dependenciesName, + lua_State *L) + : _luaFunctionName(luaFunctionName), _dependenciesName(dependenciesName),_L(L),_nbCol(nbCol) + { + } + + dataCacheDouble *newDataCache(dataCacheMap *m) + { + return new data(this,m); + } +}; + +static int newLuaFunction (lua_State *L){ + int n = lua_gettop(L); + std::vector<std::string> dependenciesName; + int nbFields = luaL_checkinteger(L, 1); + std::string luaFunctionName = std::string(luaL_checkstring(L, 2)); + for (int i=3;i<=n;i++) + dependenciesName.push_back(std::string(luaL_checkstring(L, i))); + int ITER = 1; + std::string functionName = luaFunctionName; + while (function::get(functionName, true)){ + char toto[256]; + sprintf(toto,"%d",ITER); + functionName = luaFunctionName + toto; + } + function::add(functionName,new functionLua(nbFields,luaFunctionName,dependenciesName,L)); + lua_pushstring(L, functionName.c_str()); + + return 1; +} + +static int newConstantFunction (lua_State *L){ + fullMatrix<double> * _ud = (fullMatrix<double> *) lua_touserdata(L, 1); + + int ITER = 1; + std::string functionName = "ConstantFunction"; + while (function::get(functionName, true)){ + char toto[256]; + sprintf(toto,"%d",ITER); + functionName = functionName + toto; + } + + function::add(functionName,function::newFunctionConstant(*_ud)); + lua_pushstring(L, functionName.c_str()); + return 1; +} + +int RegisterFunctions (lua_State *L) { + luaL_reg fcts[] = {{"lua", newLuaFunction }, + {"constant", newConstantFunction }}; + luaL_register(L, "createFunction", fcts); +}; + + + +#endif // HAVE LUA diff --git a/Solver/luaFunction.h b/Solver/luaFunction.h new file mode 100644 index 0000000000000000000000000000000000000000..bc161db373b85a9b23399b9a0b661c93ef3644e8 --- /dev/null +++ b/Solver/luaFunction.h @@ -0,0 +1,13 @@ +#include "GmshConfig.h" +#ifndef _LUA_FUNCTION_H_ +#define _LUA_FUNCTION_H_ +#if defined(HAVE_LUA) +// include lua stuff +extern "C" { +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +} +int RegisterFunctions (lua_State *L); +#endif // HAVE LUA +#endif // _LUA_FUNCTION_H_ diff --git a/contrib/DiscreteIntegration/Integration3D.h b/contrib/DiscreteIntegration/Integration3D.h index f0006bbbd46a268171e361ff834aacf25926d872..97becf7def0719b999d0b9f816d8108b24788fbd 100644 --- a/contrib/DiscreteIntegration/Integration3D.h +++ b/contrib/DiscreteIntegration/Integration3D.h @@ -47,7 +47,7 @@ class DI_Point // assignment DI_Point & operator=(const DI_Point & rhs); // destructor - virtual ~DI_Point () {Ls.clear();} + virtual ~DI_Point () {} // add a levelset value (adjusted to 0 if ls<ZERO_LS_TOL) into the vector Ls void addLs (const double ls); // add a levelset value evaluated into the element e @@ -218,6 +218,7 @@ class DI_Element // domain elements : -1 = outside / +1 = inside // interface elements : tag of the levelset that created the element // -1 = out of the domain border + // DI_Point *pts_; // vertices DI_Point **pts_; // vertices DI_Point **mid_; // middle vertices int polOrder_; // polynomial order of the shape functions @@ -624,8 +625,10 @@ class DI_Quad : public DI_Element class DI_Tetra : public DI_Element { + //DI_Point pts_[4]; // vertices public: DI_Tetra () { + //pts_ = new DI_Point [4]; pts_ = new DI_Point*[4]; for(int i = 0; i < 4; i++) pts_[i] = NULL; } @@ -633,6 +636,7 @@ class DI_Tetra : public DI_Element double x2, double y2, double z2, double x3, double y3, double z3) { pts_ = new DI_Point*[4]; + //pts_[0] = DI_Point(x0, y0, z0); pts_[0] = new DI_Point(x0, y0, z0); pts_[1] = new DI_Point(x1, y1, z1); pts_[2] = new DI_Point(x2, y2, z2);