You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

71 lines
2.4 KiB

#include <medusa/Medusa_fwd.hpp>
#include <Eigen/SparseCore>
#include <Eigen/IterativeLinearSolvers>
/// Basic medusa example, we are solving 2D lid driven case on unit square
/// with Dirichlet boundary conditions.
/// http://www-e6.ijs.si/medusa/wiki/index.php/Lid_driven_cavity
using namespace mm; // NOLINT
int main() {
// case setup
double dt = 0.001;
double time = 0.5;
int n = 9;
double sigma_b = 20;
double dx = 0.02;
double mu = 0.01;
double rho = 1;
double dl = 2;
// Create the domain and discretize it
BoxShape<Vec2d> box(0.0, 1.0);
DomainDiscretization<Vec2d> domain = box.discretizeWithStep(dx);
// boundary maps
Range<int> top = domain.types() == -4;
// fields declaration
VectorField2d u_1(domain.size());
ScalarFieldd p = ScalarFieldd::Zero(domain.size());
u_1.setZero();
// dirichlet boundary conditions - lid is set to {1,0}, other remain zero
u_1[top] = {1, 0};
VectorField2d u_2 = u_1;
// Find support for the nodes
domain.findSupport(FindClosest(n)); // the support for each node is the closest 9 nodes
// Construct the approximation engine, in this case a weighted least squares using monomials as
// basis functions, no weight, and scale to farthest
WLS<Gaussians<Vec2d>, NoWeight<Vec2d>,
ScaleToFarthest> wls({n, sigma_b});
// compute the shapes (we only need the Laplacian) using our WLS
auto storage = domain.computeShapes<sh::lap | sh::grad>(wls);
// construct explicit operators
auto op_v = storage.explicitVectorOperators();
auto op_s = storage.explicitOperators();
// time loop
for (int time_step = 0; time_step < std::floor(time / dt); ++time_step) {
// Navier-Stokes
for (int i : domain.interior()) {
u_2[i] = u_1[i] + dt * (-1 / rho * op_s.grad(p, i) + mu / rho * op_v.lap(u_1, i)
- op_v.grad(u_1, i) * u_1[i]);
}
for (int i : domain.all()) {
p[i] = p[i] - dl * dl * dt * rho * op_v.div(u_2, i);
}
u_1.swap(u_2);
}
// Write the solution to file
std::ofstream out_file("lid_driven_acm_2D_data.m");
out_file << "positions = " << domain.positions() << ";" << std::endl;
out_file << "u = " << u_2 << ";" << std::endl;
out_file.close();
prn(domain.size());
double Re = rho / mu;
prn(Re);
// ---------
return 0;
}