Skip to content

Commit

Permalink
--ast and GROUPS keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
gtheler committed Jul 24, 2024
1 parent 46b2755 commit 27e9880
Show file tree
Hide file tree
Showing 15 changed files with 113 additions and 60 deletions.
12 changes: 11 additions & 1 deletion src/feenox.h
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,8 @@ typedef struct material_t material_t;
typedef struct material_ll_t material_ll_t;
typedef struct distribution_t distribution_t;

// nice but not needed
// typedef struct name_item_t name_item_t;
typedef struct bc_t bc_t;
typedef struct bc_data_t bc_data_t;

Expand Down Expand Up @@ -1199,12 +1201,20 @@ struct distribution_t {
double (*eval)(distribution_t *, const double *x, material_t *material);
};

// nice but not needed
/*
struct name_item_t {
char *name;
name_item_t *next;
};
*/

struct bc_t {
char *name;
mesh_t *mesh;
// name_item_t *groups;
bc_data_t *bc_datums;
int has_explicit_groups;
// int has_explicit_groups;

UT_hash_handle hh; // for the hashed list mesh.bcs
bc_t *next; // for the linked list in each physical group
Expand Down
38 changes: 37 additions & 1 deletion src/flow/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ int feenox_initialize(int argc, char **argv) {
///op+elements_info+option `--elements_info`
///op+elements_info+desc output a document with information about the supported element types
{ "elements_info", no_argument, NULL, 'e'},
///op+ast+option `--ast`
///op+ast+desc dump an abstract syntax tree of the input
{ "ast", no_argument, NULL, 'a'},

///op+linear+option `--linear`
///op+linear+desc force FeenoX to solve the PDE problem as linear
Expand Down Expand Up @@ -122,6 +125,7 @@ int feenox_initialize(int argc, char **argv) {
}
feenox.argv_orig[i] = NULL;

int dump_ast = 0;
opterr = 0; // don't complain about unknown options, they can be for PETSc/SLEPc
while ((optc = getopt_long_only(argc, argv, "hvVc", longopts, &option_index)) != -1) {
switch (optc) {
Expand All @@ -135,7 +139,11 @@ int feenox_initialize(int argc, char **argv) {
show_version = version_info;
break;
case 'c':
feenox.check= 1;
feenox.check = 1;
break;
case 'a':
feenox.check = 1;
dump_ast = 1;
break;
case 'p':
show_version = version_available_pdes;
Expand Down Expand Up @@ -223,6 +231,34 @@ int feenox_initialize(int argc, char **argv) {
feenox_call(feenox_init_special_objects());
feenox_call(feenox_parse_main_input_file(feenox.main_input_filepath));

if (dump_ast) {
printf("{\n");
printf(" \"bcs\": [\n");
// this is a loop over a hash, not over a linked list
for (bc_t *bc = feenox.mesh.bcs; bc != NULL; bc = bc->hh.next) {
printf(" { \"name\": \"%s\",\n", bc->name);
printf(" \"groups\": [\n");

physical_group_t *physical_group = NULL;
for (physical_group = bc->mesh->physical_groups; physical_group != NULL; physical_group = physical_group->hh.next) {
bc_t *bc_inner = NULL;
LL_FOREACH(physical_group->bcs, bc_inner) {
if (bc_inner == bc) {
printf(" \"%s\"\n", physical_group->name);
}
}
}

printf(" ] }");
if (bc->hh.next != NULL) {
printf(",");
}
printf("\n");
}
printf(" ]\n");
printf("}\n");
}

return FEENOX_OK;
}

Expand Down
7 changes: 0 additions & 7 deletions src/mesh/gmsh.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,13 +181,6 @@ int feenox_mesh_read_gmsh(mesh_t *this) {
HASH_FIND_STR(feenox.mesh.materials, name, physical_group->material);
}

// same for BCs, although slightly different because there can be many
bc_t *bc = NULL;
HASH_FIND_STR(feenox.mesh.bcs, name, bc);
if (bc != NULL) {
LL_APPEND(physical_group->bcs, bc);
}

feenox_free(name);

}
Expand Down
2 changes: 1 addition & 1 deletion src/mesh/mesh.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ int feenox_instruction_mesh_read(void *arg) {

// allocate arrays for the elements that belong to a physical group
// (arrays are more efficient than a linked list)
physical_group_t *physical_group;
physical_group_t *physical_group = NULL;
for (physical_group = this->physical_groups; physical_group != NULL; physical_group = physical_group->hh.next) {
if (physical_group->n_elements != 0) {
feenox_check_alloc(physical_group->element = calloc(physical_group->n_elements, sizeof(size_t)));
Expand Down
65 changes: 48 additions & 17 deletions src/parser/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -2815,6 +2815,27 @@ int feenox_parse_material(void) {



int feenox_parse_bc_add_group(bc_t *bc, const char *physical_group_name) {
physical_group_t *physical_group = NULL;
if ((physical_group = feenox_get_or_define_physical_group_get_ptr(physical_group_name, bc->mesh, 0, 0)) == NULL) {
return FEENOX_ERROR;
}

// TODO: api
LL_APPEND(physical_group->bcs, bc);

// nice but not needed
/*
name_item_t *name_item = NULL;
feenox_check_alloc(name_item = calloc(1, sizeof(name_item_t)));
name_item->name = strdup(physical_group_name);
LLq_APPEND(bc->groups, name_item);
*/

return FEENOX_OK;

}

int feenox_parse_bc(void) {

///kw_pde+BC+usage <name>
Expand All @@ -2838,6 +2859,7 @@ int feenox_parse_bc(void) {
bc_t *bc = feenox_define_bc_get_ptr(bc_name, NULL);

char *token = NULL;
int has_explicit_groups = 0;
while ((token = feenox_get_next_token(NULL)) != NULL) {

///kw_pde+BC+usage [ MESH <name> ]
Expand All @@ -2852,27 +2874,25 @@ int feenox_parse_bc(void) {
}
feenox_free(mesh_name);

///kw_pde+BC+usage [ PHYSICAL_GROUP <name_1> PHYSICAL_GROUP <name_2> ... ]
///kw_pde+BC+usage [ GROUP <name_1> GROUP <name_2> ... ]
///kw_pde+BC+detail If the boundary condition applies to more than one physical group in the mesh,
///kw_pde+BC+detail they can be added using as many `PHYSICAL_GROUP` keywords as needed.
///kw_pde+BC+detail If at least one `PHYSICAL_GROUP` is given explicitly, then the `BC` name
///kw_pde+BC+detail is not used to try to implicitly link it to a physical group in the mesh.
} else if (strcasecmp(token, "PHYSICAL_GROUP") == 0 || strcasecmp(token, "GROUP") == 0 || strcasecmp(token, "LABEL") == 0) {

bc->has_explicit_groups = 1;
///kw_pde+BC+detail they can be added using as many `GROUP` keywords as needed.
} else if (strcasecmp(token, "GROUP") == 0 || strcasecmp(token, "LABEL") == 0) {

char *physical_group_name;
feenox_call(feenox_parser_string(&physical_group_name));
has_explicit_groups = 1;
char *physical_group_name = NULL;
feenox_call(feenox_parser_string(&physical_group_name));
feenox_call(feenox_parse_bc_add_group(bc, physical_group_name));
feenox_free(physical_group_name);

physical_group_t *physical_group = NULL;
if ((physical_group = feenox_get_or_define_physical_group_get_ptr(physical_group_name, bc->mesh, 0, 0)) == NULL) {
return FEENOX_ERROR;
} else if (strcasecmp(token, "GROUPS") == 0 || strcasecmp(token, "LABELS") == 0) {

has_explicit_groups = 1;
while ((token = feenox_get_next_token(NULL)) != NULL) {
feenox_call(feenox_parse_bc_add_group(bc, token));
}

// TODO: api
LL_APPEND(physical_group->bcs, bc);
feenox_free(physical_group_name);

break;

} else {
///kw_pde+BC+usage [ <bc_data1> <bc_data2> ... ]
///kw_pde+BC+detail Each `<bc_data>` argument is a single string whose meaning depends on the type
Expand All @@ -2886,7 +2906,18 @@ int feenox_parse_bc(void) {
return FEENOX_ERROR;
}
}
///kw_pde+BC+usage [ GROUPS <name_1> <name_2> ... ]
///kw_pde+BC+detail If the keyword `GROUPS` is given, then the rest of the tokens are parsed
///kw_pde+BC+detail as group names where the boundary condition is applied.
///kw_pde+BC+detail If either `GROUP` or `GROUPS` are given explicitly, then the `BC` name
///kw_pde+BC+detail is not used to try to implicitly link it to a physical group in the mesh.

}

if (has_explicit_groups == 0) {
feenox_call(feenox_parse_bc_add_group(bc, bc_name));
}

feenox_free(bc_name);

return FEENOX_OK;
Expand Down
1 change: 1 addition & 0 deletions src/parser/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ extern int feenox_parse_write_mesh(void);
extern int feenox_parse_write_results(void);
extern int feenox_parse_physical_group(void);
extern int feenox_parse_material(void);
extern int feenox_parse_bc_add_group(bc_t *bc, const char *physical_group_name);
extern int feenox_parse_bc(void);
extern int feenox_parse_reaction(void);
extern int feenox_parse_problem(void);
Expand Down
30 changes: 6 additions & 24 deletions src/pdes/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ int feenox_problem_parse_time_init(void) {
feenox_check_alloc(petsc_argv = calloc(2*feenox.argc, sizeof(char *)));
petsc_argv[0] = feenox.argv_orig[0];
for (int i = 0; i < feenox.argc; i++) {
if (strlen(feenox.argv_orig[i]) > 2 && feenox.argv_orig[i][0] == '-' && feenox.argv_orig[i][1] == '-') {
if (strlen(feenox.argv_orig[i]) > 2 && feenox.argv_orig[i][0] == '-' && feenox.argv_orig[i][1] == '-' &&
strcmp(feenox.argv_orig[i], "--check") && strcmp(feenox.argv_orig[i], "--ast")) {
feenox_check_alloc(petsc_argv[++petsc_argc] = strdup(feenox.argv_orig[i]+1));
char *value = NULL;
if ((value = strchr(petsc_argv[petsc_argc], '=')) != NULL) {
Expand Down Expand Up @@ -463,39 +464,20 @@ int feenox_problem_init_runtime_general(void) {
}


if (feenox.pde.mesh != NULL) {
if (feenox.pde.mesh != NULL && feenox.pde.unresolved_bcs == unresolved_bcs_detect) {

// this is a loop over a hash, not over a linked list
for (physical_group_t *physical_group = feenox.pde.mesh->physical_groups; physical_group != NULL; physical_group = physical_group->hh.next) {
if (physical_group->bcs != NULL && physical_group->n_elements == 0) {
feenox_push_error_message("physical entity '%s' has a BC but no associated elements", physical_group->name);
feenox_push_error_message("physical entity '%s' has a BC but no associated elements. Set ALLOW_UNRESOLVED_BCS if you want to skip this check.", physical_group->name);
return FEENOX_ERROR;
}

if (physical_group->material != NULL && physical_group->n_elements == 0) {
feenox_push_error_message("physical group '%s' has a material but no associated elements", physical_group->name);
feenox_push_error_message("physical group '%s' has a material but no associated elements. Set ALLOW_UNRESOLVED_BCS if you want to skip this check.", physical_group->name);
return FEENOX_ERROR;
}
}

if (feenox.pde.unresolved_bcs == unresolved_bcs_detect) {
// this is a loop over a hash, not over a linked list
for (bc_t *bc = feenox.mesh.bcs; bc != NULL; bc = bc->hh.next) {
if (bc->has_explicit_groups == 0) {
physical_group_t *physical_group;
HASH_FIND_STR(feenox.pde.mesh->physical_groups, bc->name, physical_group);

if (physical_group == NULL) {
feenox_push_error_message("boundary condition '%s' does not have a physical group in mesh file '%s'. Set ALLOW_UNRESOLVED_BCS if you want to skip this check.", bc->name, feenox.pde.mesh->file->path);
return FEENOX_ERROR;
}

if (physical_group->n_elements == 0) {
feenox_push_error_message("physical group for boundary condition '%s' does not have any elements. Set ALLOW_UNRESOLVED_BCS if you want to skip this check.", bc->name);
return FEENOX_ERROR;
}
}
}
}
}

// allocate global petsc objects
Expand Down
2 changes: 1 addition & 1 deletion tests/bunny-thermal-mpi.fee
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PHYSICAL_GROUP base DIM 2
PHYSICAL_GROUP rest DIM 2

convection_coeff = 1
BC heated h=convection_coeff Tref=1 LABEL base LABEL rest
BC heated h=convection_coeff Tref=1 GROUP base GROUP rest

SOLVE_PROBLEM

Expand Down
2 changes: 1 addition & 1 deletion tests/bunny-thermal.fee
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ PHYSICAL_GROUP base DIM 2
PHYSICAL_GROUP rest DIM 2

convection_coeff = 1
BC heated h=convection_coeff Tref=1 LABEL base LABEL rest
BC heated h=convection_coeff Tref=1 GROUPS base rest

SOLVE_PROBLEM

Expand Down
2 changes: 1 addition & 1 deletion tests/parallelepiped-from-msh.fee
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ BC B u=0 w=0
BC C u=0

# here "load" is a fantasy name
BC load tension=1 PHYSICAL_GROUP left PHYSICAL_GROUP right
BC load tension=1 GROUPS left right

SOLVE_PROBLEM

Expand Down
2 changes: 1 addition & 1 deletion tests/parallelepiped.fee
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ BC B u=0 w=0
BC C u=0

# here "load" is a fantasy name
BC load tension=1 PHYSICAL_GROUP left PHYSICAL_GROUP right
BC load tension=1 GROUP left GROUP right

SOLVE_PROBLEM

Expand Down
2 changes: 1 addition & 1 deletion tests/poisson-square.fee
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PROBLEM laplace 2d
READ_MESH square-centered.msh
BC zero phi=0 PHYSICAL_GROUP left PHYSICAL_GROUP right PHYSICAL_GROUP bottom PHYSICAL_GROUP up
BC zero phi=0 GROUPS left right bottom up
f = 1
gamg_threshold = 1e-4
SOLVE_PROBLEM
Expand Down
2 changes: 1 addition & 1 deletion tests/reaction-displ.fee
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ READ_MESH reaction.msh SCALE 1e-3
E = 70e9
nu = 0.33

BC dummy_name symmetry PHYSICAL_GROUP surf_1_1 PHYSICAL_GROUP surf_1_2 symmetry PHYSICAL_GROUP surf_1_3 PHYSICAL_GROUP surf_1_4 PHYSICAL_GROUP surf_1_6
BC dummy_name symmetry GROUPS surf_1_1 surf_1_2 surf_1_3 surf_1_4 surf_1_6
BC surf_1_5 w=-5.35655e-08

SOLVE_PROBLEM
Expand Down
2 changes: 1 addition & 1 deletion tests/reaction-force.fee
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ READ_MESH reaction.msh SCALE 1e-3
E = 70e9
nu = 0.33

BC dummy_name symmetry PHYSICAL_GROUP surf_1_1 PHYSICAL_GROUP surf_1_2 PHYSICAL_GROUP surf_1_3 PHYSICAL_GROUP surf_1_4 PHYSICAL_GROUP surf_1_6
BC dummy_name symmetry GROUPS surf_1_1 surf_1_2 surf_1_3 surf_1_4 surf_1_6
BC surf_1_5 Fz=-100

SOLVE_PROBLEM
Expand Down
4 changes: 2 additions & 2 deletions tests/wilson-2d.fee
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ READ_MESH wilson-2d.msh
k(x,y) = 1 + 0.5*T(x,y)
rhocp(x,y) = 1 + 0.5*T(x,y)

BC heat q=1 PHYSICAL_GROUP left PHYSICAL_GROUP bottom
BC temp T=limit(1e5*t,0,1) PHYSICAL_GROUP right PHYSICAL_GROUP top
BC heat q=1 GROUP left GROUP bottom
BC temp T=limit(1e5*t,0,1) GROUP right GROUP top
T_0(x,y) = 0

end_time = 17.25
Expand Down

0 comments on commit 27e9880

Please sign in to comment.