Commit 296c30bd authored by Michel Henry's avatar Michel Henry
Browse files

fix strong_boudaries

parent 3da87ef2
......@@ -1044,7 +1044,7 @@ void fluid_problem_assemble_system(FluidProblem *problem, const double *solution
printf("Boundary tag \"%s\" not found.\n", bnd->tag);
exit(1);
}
for (int i = 0; i < problem->boundaries[iphys].n_nodes; ++i){
for (int i = 0; i < problem->boundaries[iphys].n_nodes; ++i){ // to change
forced_row[problem->boundaries[iphys].nodes[i]*n_fields+bnd->row] = bnd->field;
}
}
......@@ -1095,23 +1095,80 @@ void fluid_problem_apply_boundary_conditions(FluidProblem *problem)
exit(1);
}
MeshBoundary *mbnd = &problem->boundaries[iphys];
double *x = (double*)malloc(mbnd->n_nodes*sizeof(double)*D);
double *v = (double*)malloc(mbnd->n_nodes*sizeof(double));
for (int i = 0; i < mbnd->n_nodes; ++i){
int j = mbnd->nodes[i];
for (int k = 0; k < D; ++k)
x[i*D+k] = mesh->x[j*3+k];
}
bnd->apply(mbnd->n_nodes, x, v);
// int map[problem->fields->local_size];
// fe_fields_local_map(problem->fields, problem->mesh, iel, map);
for (int i = 0; i < mbnd->n_nodes; ++i)
problem->solution[mbnd->nodes[i]*n_fields+bnd->field] = v[i]; // pas correcte
free(x);
free(v);
}
}
const FEElement *field = problem->fields->element[bnd->field];
for(int iinterface=0; iinterface < mbnd->n_interfaces; ++iinterface){
const int *interface = &mesh->interfaces[mbnd->interfaces[iinterface]*4];
const int iel = interface[0];
const int *el = &mesh->elements[iel*N_N];
int ndof_closure = field->ndof_closure;
double *x = malloc(ndof_closure*sizeof(double)*D);
double *v = malloc(ndof_closure*sizeof(double));
for(int id=0; id < ndof_closure; ++id){
int closure = (*field->closure + ndof_closure*interface[1])[id];
double xibnd[D];
for(int d=0; d < D; ++d)
xibnd[d] = field->param_coord[closure][d];
double sf[mesh->element->nlocal];
mesh->element->f(xibnd, sf);
for(int d=0; d < D; ++d){
double xx = 0;
for(int isf=0; isf<mesh->element->nlocal; ++isf){
xx += mesh->x[el[isf]*3+d]*sf[isf];
}
x[id*D+d] = xx;
}
}
bnd->apply(ndof_closure, x, v);
int map[problem->fields->local_size];
fe_fields_local_map(problem->fields, mesh, iel, map);
int imap=0;
for(int i=0; problem->fields->n; ++i){
if(i == bnd->field) break;
imap += problem->fields->element[i]->nlocal;
}
int *dofmap = &(map[imap]);
for(int id=0; id < ndof_closure; ++id){
int closure = (*field->closure + ndof_closure*interface[1])[id];
problem->solution[dofmap[closure]] = v[id];
}
free(x);
free(v);
}
}
}
// void fluid_problem_apply_boundary_conditions(FluidProblem *problem)
// {
// const Mesh *mesh = problem->mesh;
// int n_fields = fluid_problem_n_fields(problem);
// for (int ibnd = 0; ibnd < problem->n_strong_boundaries; ++ibnd) {
// StrongBoundary *bnd = problem->strong_boundaries + ibnd;
// int iphys;
// for (iphys = 0; iphys < mesh->n_boundaries; ++iphys) {
// if (strcmp(bnd->tag, mesh->boundary_names[iphys]) == 0)
// break;
// }
// if (iphys == mesh->n_boundaries){
// printf("Boundary tag \"%s\" not found.\n", bnd->tag);
// exit(1);
// }
// MeshBoundary *mbnd = &problem->boundaries[iphys];
// double *x = (double*)malloc(mbnd->n_nodes*sizeof(double)*D);
// double *v = (double*)malloc(mbnd->n_nodes*sizeof(double));
// for (int i = 0; i < mbnd->n_nodes; ++i){
// int j = mbnd->nodes[i];
// for (int k = 0; k < D; ++k)
// x[i*D+k] = mesh->x[j*3+k];
// }
// bnd->apply(mbnd->n_nodes, x, v);
// for (int i = 0; i < mbnd->n_nodes; ++i){
// problem->solution[mbnd->nodes[i]*n_fields+bnd->field] = v[i]; // pas correcte pour p2p1
// }
// free(x);
// free(v);
// }
// }
static void fluid_problem_compute_node_volume(FluidProblem *problem) {
free(problem->node_volume);
......@@ -1944,17 +2001,18 @@ void weak_boundary_values(const FEFields *fields, const Mesh *mesh, const MeshBo
double *x = malloc(bnd->n_interfaces*sizeof(double)*N_LQP*D);
for (int i = 0; i < bnd->n_interfaces; ++i){
int *interface = &mesh->interfaces[bnd->interfaces[i]*4];
int iel = interface[0];
const int *el = &mesh->elements[interface[0]*N_N];
for (int iqp = 0; iqp < N_LQP; ++iqp) {
double xiel[DIMENSION];
double xiel[D];
param_boundary_to_element(interface[1],LQP[iqp], xiel);
double phil[DIMENSION+1];
mesh->element->f(xiel, phil);
for (int id = 0; id < D; ++id){
const FEElement *mesh_element = mesh->element;
double sf[mesh_element->nlocal];
mesh_element->f(xiel, sf);
for(int id=0; id < D; ++id){
double xx = 0;
for (int iphi = 0; iphi < D+1; ++iphi) {
xx += mesh->x[el[iphi]*3+id]*phil[iphi];
for(int isf=0; isf < mesh_element->nlocal; ++isf){
xx += mesh->x[el[isf]*3+id]*sf[isf];
}
x[(i*N_LQP+iqp)*D+id] = xx;
}
......
......@@ -3,6 +3,22 @@
#include <stdio.h>
#include <string.h>
static int CLOSURE_TRIANGLE_P1[6][2] = {
{0,1},{1,2},{2,0},
{1,0},{2,1},{0,2}};
static int CLOSURE_TRIANGLE_P2[6][3] = {
{0,1,3},{1,2,4},{2,0,5},
{1,0,3},{2,1,4},{0,2,5}};
static double XI_TRIANGLE_P1[][D] = {
{0.0,0.0},{1.0,0.0},{0.0,1.0}};
static double XI_TRIANGLE_P2[][D] = {
{0.0,0.0},{1.0,0.0},{0.0,1.0},
{0.5,0.0},{0.5,0.5},{0.0,0.5}};
static void fe_f_line_p1(const double *xi, double *f) {
f[0] = 1-xi[0];
f[1] = xi[0];
......@@ -77,8 +93,10 @@ static void fe_df_tetrahedron_p1(const double *xi, const double dxidx[][D], doub
df[2][d] = dxidx[1][d];
df[3][d] = dxidx[2][d];
}
}
FEElement *fe_element_new(const char *etype) {
FEElement *fe = malloc(sizeof(FEElement));
if (strcmp(etype,"triangle_p1") == 0) {
......@@ -87,6 +105,9 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 0;
fe->n[2] = 0;
fe->n[3] = 0;
fe->ndof_closure = 2;
fe->closure = CLOSURE_TRIANGLE_P1;
fe->param_coord = XI_TRIANGLE_P1;
fe->f = fe_f_triangle_p1;
fe->df = fe_df_triangle_p1;
}
......@@ -96,6 +117,9 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 0;
fe->n[2] = 3;
fe->n[3] = 0;
fe->ndof_closure = 2;
fe->closure = CLOSURE_TRIANGLE_P1;
fe->param_coord = XI_TRIANGLE_P1;
fe->f = fe_f_triangle_p1;
fe->df = fe_df_triangle_p1;
}
......@@ -105,6 +129,9 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 1;
fe->n[2] = 0;
fe->n[3] = 0;
fe->ndof_closure = 3;
fe->closure = CLOSURE_TRIANGLE_P2;
fe->param_coord = XI_TRIANGLE_P2;
fe->f = fe_f_triangle_p2;
fe->df = fe_df_triangle_p2;
}
......@@ -114,6 +141,7 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 0;
fe->n[2] = 0;
fe->n[3] = 0;
fe->ndof_closure = 1;
fe->f = fe_f_line_p1;
fe->df = fe_df_line_p1;
}
......@@ -123,6 +151,7 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 1;
fe->n[2] = 0;
fe->n[3] = 0;
fe->ndof_closure = 1;
fe->f = fe_f_line_p2;
fe->df = fe_df_line_p2;
}
......@@ -132,6 +161,7 @@ FEElement *fe_element_new(const char *etype) {
fe->n[1] = 0;
fe->n[2] = 0;
fe->n[3] = 0;
fe->ndof_closure = 3;
fe->f = fe_f_tetrahedron_p1;
fe->df = fe_df_tetrahedron_p1;
}
......
......@@ -8,6 +8,9 @@
struct FEElementStruct{
int nlocal;
int n[DIMENSION+1];
int ndof_closure;
int (*closure)[];
double (*param_coord)[D];
void (*f)(const double *xi, double *f);
void (*df)(const double *xi, const double dxidx[D][D], double f[][D]);
};
......
......@@ -180,7 +180,6 @@ Mesh *mesh_new_from_elements(int n_nodes, double *x, int n_elements, int *elemen
const char *types[] = {"triangle_p1","triangle_p1",NULL};
#endif
m->coord_fields = fe_fields_new(types);
m->n_elements = n_elements;
m->elements = malloc(n_elements*sizeof(int)*(DIMENSION+1));
memcpy(m->elements,elements,(DIMENSION+1)*sizeof(int)*n_elements);
......@@ -208,6 +207,7 @@ Mesh *mesh_new_from_elements(int n_nodes, double *x, int n_elements, int *elemen
}
MeshBoundary *mesh_boundaries_create(const Mesh *m) {
// To extend for p2p1
MeshBoundary *b = malloc(sizeof(MeshBoundary)*m->n_boundaries);
for (int i = 0; i < m->n_boundaries; ++i) {
b[i].n_nodes = 0;
......
......@@ -55,8 +55,8 @@ Mesh *mesh_new_from_elements(int n_nodes, double *x, int n_elements, int *elemen
typedef struct {
int n_interfaces;
int *interfaces;
int n_nodes;
int *nodes;
int n_nodes;// to delete
int *nodes; // to delete
} MeshBoundary;
#if DIMENSION == 2
......
......@@ -71,11 +71,6 @@ fluid.set_wall_boundary("Bottom", velocity=[0,0], pressure = 0)
fluid.set_wall_boundary("Top", velocity=[1.0,0])
time_integration.iterate(fluid,None,10)
# if strong boundary on periodic line, it should be forced on both sides
# fluid.set_strong_boundary("Right",2,0)
# fluid.set_strong_boundary("Left",2,0)
# Particle Problem
p = scontact.ParticleProblem(2)
p.load_msh_boundaries("mesh.msh", ["Top", "Bottom", "Left", "Right"])
......
......@@ -26,5 +26,5 @@ Physical Line("RightUp") = {5};
Physical Line("Bottom") = {3};
Physical Line("Top") = {6};
Physical Surface("Domain") = {1};
Physical Point("PtFix") = {1};
// Physical Point("PtFix") = {1};
Mesh.MshFileVersion = 2;
......@@ -73,6 +73,10 @@ class Poiseuille(unittest.TestCase) :
fluid.set_open_boundary("RightUp",pressure=0)
fluid.set_open_boundary("RightDown",pressure=0)
fluid.set_strong_boundary("LeftUp", 1, 0)
fluid.set_strong_boundary("LeftUp", 0, lambda x : 1/(20*mu)*x[:,1]*(1-x[:, 1]))
fluid.set_strong_boundary("LeftDown", 0, lambda x : 1/(20*mu)*x[:,1]*(1-x[:, 1]))
fluid.set_strong_boundary("LeftDown", 1, 0)
ii = 0
t = 0
......@@ -87,7 +91,7 @@ class Poiseuille(unittest.TestCase) :
tic = time.perf_counter()
while ii < 100 :
#Fluid solver
time_integration.iterate(fluid,None,dt,check_residual_norm=1e-5)
time_integration.iterate(fluid,None,dt,check_residual_norm=-1)
t += dt
#Output files writting
if ii %outf == 0 :
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment