### Last Finite Differences not working required several other components

parent cdc8dd42
 ... ... @@ -10,6 +10,7 @@ #define CENTRAL 0 #define CENTRAL_B_ONE_SIDE 1 #define FORWARD 2 #include "util/mathutil.hpp" #include "Vector/map_vector.hpp" ... ... @@ -63,6 +64,13 @@ class D */ inline static void value(grid_key_dx & pos, const grid_sm & gs, std::unordered_map & cols, typename Sys_eqs::stype coeff) { // if the system is staggered the CENTRAL derivative is equivalent to a forward derivative if (is_grid_staggered::value() == true) { D::value(pos,gs,cols,coeff); return; } // forward if (Sys_eqs::boundary[d] == PERIODIC ) { ... ... @@ -227,5 +235,57 @@ public: }; /*! \brief Derivative FORWARD on direction i * * */ template class D { public: /*! \brief fill the row * * */ inline static void value(grid_key_dx & pos, const grid_sm & gs, std::unordered_map & cols, typename Sys_eqs::stype coeff) { // forward if (Sys_eqs::boundary[d] == PERIODIC ) { long int old_val = pos.get(d); pos.set_d(d, openfpm::math::positive_modulo(pos.get(d) + 1, gs.size(d))); arg::value(pos,gs,cols,coeff); pos.set_d(d,old_val); } else { long int old_val = pos.get(d); pos.set_d(d, pos.get(d) + 1); arg::value(pos,gs,cols,coeff); pos.set_d(d,old_val); } // backward arg::value(pos,gs,cols,-coeff); } /*! \brief Calculate the position where the derivative is calculated * * In case on non staggered case this function just return pos, in case of staggered, * it calculate where the operator is calculated on a staggered grid * * \param pos from the position * \param fld Field we are deriving, if not provided the function just return pos * \param s_pos position of the properties in the staggered grid * */ inline static grid_key_dx position(grid_key_dx & pos, long int fld = -1, const openfpm::vector> & s_pos = openfpm::vector>()) { return pos; } }; #endif /* OPENFPM_NUMERICS_SRC_FINITEDIFFERENCE_DERIVATIVE_HPP_ */
 ... ... @@ -22,19 +22,106 @@ template class FDScheme { // Padding Padding pd; // Sparse Matrix openfpm::vector> trpl; openfpm::vector b; // Domain Grid informations const grid_sm & gs; // mapping grid grid_dist_id,Sys_eqs::grid_type::decomposition> g_map; // row of the matrix size_t row; // row on b size_t row_b; /*! \brief Check if the Matrix is consistent * */ void consistency() { // A and B must have the same rows if (row != row_b) std::cerr << "Error " << __FILE__ << ":" << __LINE__ << "the term B and the Matrix A for Ax=B must contain the same number of rows\n"; // Indicate all the non zero rows openfpm::vector nz_rows; nz_rows.resize(row_b); for (size_t i = 0 ; i < trpl.size() ; i++) { nz_rows.get(trpl.get(i).i) = true; } // Indicate all the non zero colums openfpm::vector nz_cols; for (size_t i = 0 ; i < trpl.size() ; i++) { nz_cols.get(trpl.get(i).j) = true; } // all the rows must have a non zero element for (size_t i = 0 ; i < nz_rows.size() ; i++) { if (nz_rows.get(i) == false) std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix not all the row are filled\n"; } // all the colums must have a non zero element for (size_t i = 0 ; i < nz_cols.size() ; i++) { if (nz_cols.get(i) == false) std::cerr << "Error: " << __FILE__ << ":" << __LINE__ << " Ill posed matrix not all the row are filled\n"; } } public: /*! \brief Constructor * * \param pd Padding * \param gs grid infos where Finite differences work * */ FDScheme(Padding & pd, const grid_sm & gs) :pd(pd),gs(gs) { // Counter size_t cnt = 0; // Resize the b term b.resize(gs.size()); // Create the re-mapping-grid auto it = g_map.getDomainIterator(); while (it.isNext()) { auto key = it.get(); g_map.get(key) = cnt; ++cnt; ++it; } } /*! \brief Impose an operator * * * */ template void impose(T & op, const grid_sm & gs , grid_dist_iterator_sub it) template void imposeA(const T & op , grid_dist_iterator_sub it) { size_t lin = 0; std::unordered_map cols; // iterate all the grid points ... ... @@ -54,7 +141,7 @@ public: for ( auto it = cols.begin(); it != cols.end(); ++it ) { trpl.add(); trpl.last().i = lin; trpl.last().i = row; trpl.last().j = it->first; trpl.last().value = it->second; ... ... @@ -64,25 +151,29 @@ public: cols.clear(); std::cout << "\n"; ++row; ++it; } } /*! \brief produce the Matrix /*! \brief Impose an operator * * * \tparam Syst_eq System of equations, or a single equation * */ template SparseMatrix getMatrix(const Grid & g) void imposeB(typename Sys_eqs::stype num , grid_dist_iterator_sub it) { #ifdef SE_CLASS1 if (Sys_eqs::num_cfields) std::cerr << __FILE__ << ":" << __LINE__ << " if you do not provide ConstantFields in getMatrix, the system should not contain any constant field, while" << Sys_eqs::num_cfields << "\n"; #endif std::unordered_map cols; // iterate all the grid points while (it.isNext()) { const ConstField fld[Sys_eqs::num_cfields]; b.get(row_b) = num; getMatrix(g,fld); ++row_b; ++it; } } /*! \brief produce the Matrix ... ... @@ -90,31 +181,13 @@ public: * \tparam Syst_eq System of equations, or a single equation * */ template SparseMatrix getMatrix(const Grid & g, const ConstField(& fld)[Sys_eqs::num_cfields] ) template SparseMatrix getMatrix() { // iterate across the full domain auto it = g.getDomainIterator(); auto g_sm = g.getGrid(); Sys_eqs eqs(); // iterate all the grid points while (it.isNext()) { // get the position auto key = it.get(); // convert into global coordinate the position auto keyg = g.getGKey(key); // Convert local key into global key size_t row = g_sm.LidId(keyg); #ifdef SE_CLASS1 consistency(); #endif eqs.value(keyg,trpl); ++it; } } }; ... ...
 ... ... @@ -59,7 +59,7 @@ struct syss_nn static const unsigned int nvar = 1; static const unsigned int ord = EQS_FIELD; static const unsigned int grid = STAGGERED_GRID; static const unsigned int grid_type = STAGGERED_GRID; // boundary at X and Y static const bool boundary[]; ... ... @@ -78,7 +78,7 @@ struct syss_pp static const unsigned int nvar = 1; static const unsigned int ord = EQS_FIELD; static const unsigned int grid = STAGGERED_GRID; static const unsigned int grid_type = STAGGERED_GRID; // boundary at X and Y static const bool boundary[]; ... ... @@ -312,6 +312,52 @@ BOOST_AUTO_TEST_CASE( fd_test_use_periodic) BOOST_REQUIRE_EQUAL(cols_y[14*16+15],-1); } BOOST_AUTO_TEST_CASE( fd_test_use_staggered_non_periodic) { // grid size size_t sz[2]={16,16}; // grid_sm grid_sm<2,void> ginfo(sz); // Create a derivative row Matrix grid_key_dx<2> key11(1,1); grid_key_dx<2> key00(0,0); grid_key_dx<2> key22(2,2); grid_key_dx<2> key1515(15,15); // filled colums std::unordered_map cols_x; std::unordered_map cols_y; D,syss_pp>::value(key11,ginfo,cols_x,1); D,syss_pp>::value(key11,ginfo,cols_y,1); BOOST_REQUIRE_EQUAL(cols_x.size(),2); BOOST_REQUIRE_EQUAL(cols_y.size(),2); BOOST_REQUIRE_EQUAL(cols_x[17+1],1); BOOST_REQUIRE_EQUAL(cols_x[17],-1); BOOST_REQUIRE_EQUAL(cols_y[17+16],1); BOOST_REQUIRE_EQUAL(cols_y[17],-1); cols_x.clear(); cols_y.clear(); D,syss_pp>::value(key00,ginfo,cols_x,1); D,syss_pp>::value(key00,ginfo,cols_y,1); BOOST_REQUIRE_EQUAL(cols_x.size(),2); BOOST_REQUIRE_EQUAL(cols_y.size(),2); BOOST_REQUIRE_EQUAL(cols_x[1],1); BOOST_REQUIRE_EQUAL(cols_x[0],-1); BOOST_REQUIRE_EQUAL(cols_y[16],1); BOOST_REQUIRE_EQUAL(cols_y[0],-1); } /////////////// Laplacian test BOOST_AUTO_TEST_CASE( fd_test_lap_use_periodic) ... ...
 ... ... @@ -132,7 +132,7 @@ public: static void value(grid_key_dx & pos, const grid_sm & gs, std::unordered_map & cols, typename Sys_eqs::stype coeff) { if (Sys_eqs::ord == EQS_FIELD) cols[gs.LinId(pos) + f] += coeff; cols[gs.LinId(pos)*Sys_eqs::nvar + f] += coeff; else cols[gs.LinId(pos) + f * gs.size()] += coeff; } ... ...
 ... ... @@ -44,13 +44,16 @@ const bool lid_nn::boundary[] = {NON_PERIODIC,NON_PERIODIC}; // Constant Field struct eta { float val() {return 1.0;} typedef void const_field; static float val() {return 1.0;} }; // Model the equations constexpr unsigned int v[] = {0,1}; constexpr unsigned int P = 2; constexpr unsigned int ic = 2; typedef Field v_x; typedef Field v_y; ... ... @@ -72,7 +75,8 @@ typedef sum vy_eq; typedef D dx_vx; typedef D dy_vy; typedef sum incompressibility; typedef sum ic_eq; BOOST_AUTO_TEST_SUITE( eq_test_suite ) ... ... @@ -87,6 +91,7 @@ BOOST_AUTO_TEST_CASE( lid_driven_cavity ) Ghost<2,float> g(0.01); size_t sz[] = {32,32}; Padding<2> pd({1,2},{1,2}); // Initialize the global VCluster init_global_v_cluster(&boost::unit_test::framework::master_test_suite().argc,&boost::unit_test::framework::master_test_suite().argv); ... ... @@ -95,19 +100,79 @@ BOOST_AUTO_TEST_CASE( lid_driven_cavity ) grid_dist_id<2,float,scalar,CartDecomposition<2,float>> g_dist(sz,domain,g); // Distributed grid FDScheme fd; FDScheme fd(pd, g_dist.getGridInfo()); // start and end of the bulk grid_key_dx<2> bulk_start(1,1); grid_key_dx<2> bulk_end(sz[0]-1,sz[1]-1); // Impose the vx equation vx_eq vx; fd.impose(vx, g_dist.getGridInfo() , g_dist.getSubDomainIterator(bulk_start,bulk_end)); // Impose the vy equation vy_eq vy; fd.impose(vy, g_dist.getGridInfo(), g_dist.getSubDomainIterator(bulk_start,bulk_end)); grid_key_dx<2> bulk_start(0,0); grid_key_dx<2> bulk_end(sz[0],sz[1]); // Impose the vx and vy equation in the bulk fd.imposeA(vx_eq(), g_dist.getSubDomainIterator(bulk_start,bulk_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bulk_start,bulk_end)); fd.imposeA(vy_eq(), g_dist.getSubDomainIterator(bulk_start,bulk_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bulk_start,bulk_end)); fd.imposeA(ic_eq(), g_dist.getSubDomainIterator(bulk_start,bulk_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bulk_start,bulk_end)); // Boundary condition on the left grid_key_dx<2> bleft_start(0,-1); grid_key_dx<2> bleft_end(0,33); fd.imposeA(v_x(), g_dist.getSubDomainIterator(bleft_start,bleft_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bleft_start,bleft_end)); // Boundary condition on the right grid_key_dx<2> bright_start(32,-1); grid_key_dx<2> bright_end(32,33); fd.imposeA(v_x(), g_dist.getSubDomainIterator(bright_start,bright_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bright_start,bright_end)); // Padding condition Pressure Left grid_key_dx<2> pleft_start(-1,0); grid_key_dx<2> pleft_end(-1,31); fd.imposeA(Prs(), g_dist.getSubDomainIterator(bleft_start,bleft_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bleft_start,bleft_end)); // Padding condition Pressure Right grid_key_dx<2> pright_start(32,-1); grid_key_dx<2> pright_end(33,33); fd.imposeA(Prs(), g_dist.getSubDomainIterator(pright_start,pright_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(pright_start,pright_end)); // Padding condition vy Right grid_key_dx<2> pvright_start(33,-1); grid_key_dx<2> pvright_end(33,33); fd.imposeA(v_y(), g_dist.getSubDomainIterator(pvright_start,pright_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(pvright_start,pright_end)); // Padding Bottom pressure grid_key_dx<2> pbot_start(0,-1); grid_key_dx<2> pbot_end(31,-1); fd.imposeA(Prs(), g_dist.getSubDomainIterator(pbot_start,pbot_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(pbot_start,pbot_end)); // Bottom boundary condition vy grid_key_dx<2> bbot_start(-1,0); grid_key_dx<2> bbot_end(33,0); fd.imposeA(v_y(), g_dist.getSubDomainIterator(bbot_start,bbot_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(bbot_start,bbot_end)); // Padding top pressure grid_key_dx<2> ptop_start(0,32); grid_key_dx<2> ptop_end(31,33); fd.imposeA(Prs(), g_dist.getSubDomainIterator(ptop_start,ptop_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(ptop_start,ptop_end)); // Top boundary condition v_y grid_key_dx<2> btop_start(-1,32); grid_key_dx<2> btop_end(33,32); fd.imposeA(v_y(), g_dist.getSubDomainIterator(btop_start,btop_end)); fd.imposeB(1.0, g_dist.getSubDomainIterator(btop_start,btop_end)); // Padding top v_x grid_key_dx<2> pvtop_start(0,33); grid_key_dx<2> pvtop_end(31,33); fd.imposeA(v_x(), g_dist.getSubDomainIterator(pvtop_start,pvtop_end)); fd.imposeB(0.0, g_dist.getSubDomainIterator(pvtop_start,pvtop_end)); } BOOST_AUTO_TEST_SUITE_END() ... ...
 ... ... @@ -36,7 +36,7 @@ struct sum_functor_value /*! \brief constructor * */ sum_functor_value(grid_key_dx & key, const grid_sm & gs, typename last::stype coeff) sum_functor_value(grid_key_dx & key, const grid_sm & gs, std::unordered_map & cols, typename last::stype coeff) :cols(cols),gs(gs),key(key),coeff(coeff) {}; ... ... @@ -75,7 +75,7 @@ struct sum inline static void value(grid_key_dx & pos, const grid_sm & gs, std::unordered_map & cols, typename Sys_eqs::stype coeff) { // Sum functor sum_functor_value sm(pos,gs,coeff); sum_functor_value sm(pos,gs,cols,coeff); // for each element in the expression calculate the non-zero Matrix elements boost::mpl::for_each_ref< boost::mpl::range_c >(sm); ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!