Skip to content

Commit dc2cde6

Browse files
committed
non-linear quasi-static
1 parent a30f519 commit dc2cde6

File tree

13 files changed

+163
-69
lines changed

13 files changed

+163
-69
lines changed

.gitignore

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@ auto_links.m4
5656
nbproject
5757

5858
# outputs of "make check"
59+
*.pvd
5960
mesh2d.msh
60-
mesh2d.vtk
61+
mesh2d*.vtk
6162
laplace-square.msh
6263
nafems-t4-result.msh
6364
nafems-le1*.vtk
@@ -67,51 +68,53 @@ encased_rod*.vtk
6768
nafems-le*.msh
6869
spinning-disk-*.msh
6970
square-f.msh
70-
square_tmp.vtk
71-
cube-radial.vtk
71+
square_tmp*.vtk
72+
cube-radial*.vtk
7273
long-bar-*.msh
7374
map-*.msh
74-
mesh2d.vtk
75+
mesh2d*.vtk
7576
spinning-disk-parallel-*.vtk
7677
thermal-square*.msh
77-
thermal-square.vtk
78+
thermal-square*.vtk
7879
thermal-two-squares-*.msh
7980
ray-effect-*-?.msh
8081
orthotropic-beam-*.msh
81-
heater-cylinder-inches.vtk
82-
poisson-square.msh
83-
reaction-force.vtk
82+
heater-cylinder-inches*.vtk
83+
reaction-force*.vtk
8484
ray-effect-diffusion-*.msh
8585
bunny*.vtk
8686
bunny*.msh
8787
2dpwr-*.vtk
8888
two-is-2.txt
8989
circle*.msh
9090
airfoil-converged.msh
91-
airfoil-converged.vtk
91+
airfoil-converged*.vtk
9292
circle_perimeter*.dat
9393
wilson-2d*.vtk
94-
2dpwr-eighth.vtu
95-
2dpwr-quarter.vtu
96-
beam-ldef-hex20.vtu
97-
beam-ldef-hex27.vtu
98-
beam-ldef-hex8.vtu
99-
beam-ldef-tet10.vtu
100-
beam-ldef-tet4.vtu
94+
2dpwr-eighth*.vtu
95+
2dpwr-quarter*.vtu
96+
beam-ldef-hex20*.vtu
97+
beam-ldef-hex27*.vtu
98+
beam-ldef-hex8*.vtu
99+
beam-ldef-tet10*.vtu
100+
beam-ldef-tet4*.vtu
101101
beam-orthotropic-hex20.msh
102102
beam-orthotropic-hex27.msh
103103
beam-orthotropic-hex8.msh
104104
beam-orthotropic-tet10.msh
105105
beam-orthotropic-tet4.msh
106106
heater-cylinder-inches-results.msh
107-
heater-cylinder-inches.vtu
108-
reaction-force.vtu
109-
two-cubes-isotropic-functions.vtu
110-
hex8-ldef.vtk
111-
hex8-single-stretched-linear.vtk
112-
hex8-single-stretched-neohookean.vtk
113-
hex8-single-stretched-svk.vtk
107+
heater-cylinder-inches*.vtu
108+
reaction-force*.vtu
109+
two-cubes-isotropic-functions*.vtu
110+
hex8-ldef*.vtk
111+
hex8-single-stretched-linear*.vtk
112+
hex8-single-stretched-neohookean*.vtk
113+
hex8-single-stretched-svk*.vtk
114114
spooles.out
115115
wilson-2d-*.vtk
116116
bunny.msh
117117
Stanford_Bunny.stl
118+
poisson-square.vtu
119+
hex8-ldef.txt
120+
beam-orthotropic-*.vtu

autogen.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ echo -n "creating src/Makefile.am... "
9090

9191
cd src/pdes
9292

93-
automatic="// automatically generated by autogen.sh on $(date)"
93+
# automatic="// automatically generated by autogen.sh on $(date)"
94+
automatic="// automatically generated by autogen.sh"
9495

9596
echo ${automatic} > methods.h
9697
echo ${automatic} > parse.c

src/feenox.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1958,7 +1958,7 @@ struct feenox_t {
19581958
Mat JM; // jacobian for mass matrix = M'*phi_dot
19591959
Mat Jb; // jacobian for rhs vector = dq/dT for both volumetric and BCs
19601960
Mat J_snes; // jacobian for SNES
1961-
Mat J_tran; // jacobian for TS
1961+
Mat J_ts; // jacobian for TS
19621962

19631963
PetscScalar *eigenvalue; // eigenvalue vector
19641964
Vec *eigenvector; // eivenvectors vector

src/pdes/build.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,11 @@ int feenox_problem_build_element_volumetric(element_t *this) {
271271
feenox_debug_print_gsl_matrix(feenox.fem.Ki, stdout);
272272
printf("JKi\n");
273273
feenox_debug_print_gsl_matrix(feenox.fem.JKi, stdout);
274-
*/
274+
printf("fi\n");
275+
feenox_debug_print_gsl_vector(feenox.fem.fi, stdout);
276+
printf("bi\n");
277+
feenox_debug_print_gsl_vector(feenox.fem.bi, stdout);
278+
*/
275279

276280
if (feenox.pde.has_stiffness) {
277281
petsc_call(MatSetValues(feenox.pde.K, feenox.fem.current_GJ, l, feenox.fem.current_GJ, l, gsl_matrix_ptr(feenox.fem.Ki, 0, 0), ADD_VALUES));

src/pdes/petsc_snes.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*------------ -------------- -------- --- ----- --- -- - -
22
* feenox's non-linear solver using PETSc routines
33
*
4-
* Copyright (C) 2020--2021 Jeremy Theler
4+
* Copyright (C) 2020--2025 Jeremy Theler
55
*
66
* This file is part of FeenoX <https://www.seamplex.com/feenox>.
77
*
@@ -169,7 +169,7 @@ PetscErrorCode feenox_snes_residual(SNES snes, Vec phi, Vec r, void *ctx) {
169169
}
170170

171171

172-
PetscErrorCode feenox_snes_jacobian(SNES snes,Vec phi, Mat J_snes, Mat P, void *ctx) {
172+
PetscErrorCode feenox_snes_jacobian(SNES snes, Vec phi, Mat J_snes, Mat P, void *ctx) {
173173

174174
// J_snes = (K + JK - Jb)_bc
175175
// TODO: we want SAME_NONZERO_PATTERN!

src/pdes/petsc_ts.c

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ int feenox_problem_solve_petsc_transient(void) {
3737
feenox_call(feenox_problem_solve_petsc_nonlinear());
3838
petsc_call(SNESDestroy(&feenox.pde.snes));
3939
feenox.pde.snes = NULL;
40+
4041
}
4142
} else {
4243
feenox_function_to_phi(feenox.pde.initial_condition, feenox.pde.phi);
@@ -50,8 +51,10 @@ int feenox_problem_solve_petsc_transient(void) {
5051
if (feenox.pde.initial_condition != NULL) {
5152
feenox_call(feenox_problem_build());
5253
}
53-
petsc_call(MatDuplicate(feenox.pde.has_jacobian_K ? feenox.pde.JK : feenox.pde.K, MAT_COPY_VALUES, &feenox.pde.J_tran));
54-
petsc_call(TSSetIJacobian(feenox.pde.ts, feenox.pde.J_tran, feenox.pde.J_tran, feenox_ts_jacobian, NULL));
54+
55+
feenox_check_alloc(feenox.pde.J_ts = feenox_problem_create_matrix("J_ts"));
56+
// petsc_call(MatDuplicate(feenox.pde.has_jacobian_K ? feenox.pde.JK : feenox.pde.K, MAT_COPY_VALUES, &feenox.pde.J_ts));
57+
petsc_call(TSSetIJacobian(feenox.pde.ts, feenox.pde.J_ts, feenox.pde.J_ts, feenox_ts_jacobian, NULL));
5558

5659
petsc_call(TSSetProblemType(feenox.pde.ts, (feenox.pde.math_type == math_type_linear) ? TS_LINEAR : TS_NONLINEAR));
5760

@@ -118,11 +121,6 @@ int feenox_problem_setup_ts(TS ts) {
118121
// petsc_call(TSSetMaxStepRejections(feenox.pde.ts, 10000));
119122
// petsc_call(TSSetMaxSNESFailures(feenox.pde.ts, 1000));
120123

121-
// options overwrite
122-
petsc_call(TSSetFromOptions(ts));
123-
// TODO: this guy complains about DM (?)
124-
// petsc_call(TSSetUp(ts));
125-
126124
SNES snes;
127125
petsc_call(TSGetSNES(ts, &snes));
128126
if (snes != NULL) {
@@ -135,65 +133,88 @@ int feenox_problem_setup_ts(TS ts) {
135133
}
136134
}
137135

136+
// options overwrite
137+
petsc_call(TSSetFromOptions(ts));
138138

139139

140140
return FEENOX_OK;
141141
}
142142

143143
PetscErrorCode feenox_ts_residual(TS ts, PetscReal t, Vec phi, Vec phi_dot, Vec r, void *ctx) {
144144

145-
// static int count = 0;
146-
feenox_var_value(feenox_special_var(t)) = t;
147-
145+
feenox_special_var_value(t) = t;
146+
147+
// TODO: store in a global temporary vector
148+
Vec phi_bc;
149+
petsc_call(VecDuplicate(phi, &phi_bc));
150+
petsc_call(VecCopy(phi, phi_bc));
151+
152+
feenox_call(feenox_problem_dirichlet_eval());
148153
if (feenox.pde.math_type == math_type_nonlinear) {
149-
feenox_call(feenox_problem_phi_to_solution(phi, 0));
154+
feenox_call(feenox_problem_dirichlet_set_phi(phi_bc));
155+
feenox_call(feenox_problem_phi_to_solution(phi_bc, 0));
156+
if (feenox.pde.phi_bc != NULL) {
157+
petsc_call(VecCopy(phi_bc, feenox.pde.phi_bc));
158+
}
150159
}
151160

152161
// TODO: for time-dependent neumann BCs it should not be needed to re-build the whole matrix, just the RHS
153162
feenox_call(feenox_problem_build());
154163

155-
// TODO: be smart about this too
156-
feenox_call(feenox_problem_dirichlet_eval());
157-
158-
// compute the residual R(t,phi,phi_dot) = M*(phi_dot)_dirichlet + K*(phi)_dirichlet - b
164+
// compute the residual R(t,phi,phi_dot) = M*(phi_dot)_dirichlet + K*(phi)_dirichlet - b (linear)
165+
// = M*(phi_dot)_dirichlet + f(phi)_dirichlet - b (non-linear)
159166

160-
// TODO: store in a global temporary vector
161-
Vec tmp;
162-
petsc_call(VecDuplicate(phi, &tmp));
163-
167+
// TODO: start with the K/f term and add the mass later
164168
// set dirichlet BCs on the time derivative and multiply by M
165169
if (feenox.pde.M != NULL) {
166-
petsc_call(VecCopy(phi_dot, tmp));
167-
feenox_call(feenox_problem_dirichlet_set_phi_dot(tmp));
168-
petsc_call(MatMult(feenox.pde.M, tmp, r));
170+
Vec phi_dot_bc;
171+
petsc_call(VecDuplicate(phi, &phi_dot_bc));
172+
petsc_call(VecCopy(phi_dot, phi_dot_bc));
173+
feenox_call(feenox_problem_dirichlet_set_phi_dot(phi_dot_bc));
174+
petsc_call(MatMult(feenox.pde.M, phi_dot_bc, r));
175+
petsc_call(VecDestroy(&phi_dot_bc));
169176
} else {
170177
petsc_call(VecZeroEntries(r));
171178
}
172179

173-
// set dirichlet BCs on the solution and multiply by K
174-
// TODO: only if the problem does not compute an actual residual!
175-
petsc_call(VecCopy(phi, tmp));
176-
feenox_call(feenox_problem_dirichlet_set_phi(tmp));
177-
178-
petsc_call(MatMultAdd(feenox.pde.K, tmp, r, r));
179-
petsc_call(VecDestroy(&tmp));
180+
// set dirichlet BCs on the solution compute the residual
181+
if (feenox.pde.has_internal_fluxes) {
182+
// if the problem provides an internal flux, use it
183+
petsc_call(VecCopy(feenox.pde.f, r));
184+
} else {
185+
// otherwise make it up from the stiffness and the solution
186+
petsc_call(MatMultAdd(feenox.pde.K, phi_bc, r, r));
187+
}
188+
petsc_call(VecDestroy(&phi_bc));
180189

181190
petsc_call(VecAXPY(r, -1.0, feenox.pde.b));
182191

183192
// set dirichlet bcs on the residual
184193
feenox_call(feenox_problem_dirichlet_set_r(r, phi));
185-
194+
186195
return FEENOX_OK;
187196
}
188197

189-
PetscErrorCode feenox_ts_jacobian(TS ts, PetscReal t, Vec phi, Vec phi_dot, PetscReal s, Mat J, Mat P, void *ctx) {
198+
PetscErrorCode feenox_ts_jacobian(TS ts, PetscReal t, Vec phi, Vec phi_dot, PetscReal s, Mat J_ts, Mat P, void *ctx) {
190199

191-
// return (K + s*M)_dirichlet
192-
petsc_call(MatCopy(feenox.pde.K, J, SAME_NONZERO_PATTERN));
193-
if (feenox.pde.M != NULL) {
194-
petsc_call(MatAXPY(J, s, feenox.pde.M, SAME_NONZERO_PATTERN));
200+
petsc_call(MatAssemblyBegin(feenox.pde.K, MAT_FINAL_ASSEMBLY));
201+
petsc_call(MatAssemblyEnd(feenox.pde.K, MAT_FINAL_ASSEMBLY));
202+
petsc_call(MatAssemblyBegin(J_ts, MAT_FINAL_ASSEMBLY));
203+
petsc_call(MatAssemblyEnd(J_ts, MAT_FINAL_ASSEMBLY));
204+
205+
// return (K + JK - Jb + s*M)_bc
206+
petsc_call(MatCopy(feenox.pde.K, J_ts, DIFFERENT_NONZERO_PATTERN));
207+
if (feenox.pde.has_jacobian_K) {
208+
petsc_call(MatAXPY(J_ts, +1.0, feenox.pde.JK, DIFFERENT_NONZERO_PATTERN));
209+
}
210+
if (feenox.pde.has_jacobian_b) {
211+
petsc_call(MatAXPY(J_ts, -1.0, feenox.pde.Jb, DIFFERENT_NONZERO_PATTERN));
212+
}
213+
214+
if (feenox.pde.has_mass) {
215+
petsc_call(MatAXPY(J_ts, s, feenox.pde.M, DIFFERENT_NONZERO_PATTERN));
195216
}
196-
feenox_call(feenox_problem_dirichlet_set_J(J));
217+
feenox_call(feenox_problem_dirichlet_set_J(J_ts));
197218

198219
return FEENOX_OK;
199220
}

src/pdes/thermal/init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ int feenox_problem_init_runtime_thermal(void) {
135135
thermal.q.non_uniform = feenox_depends_on_space(thermal.q.dependency_variables);
136136
thermal.q.non_linear = feenox_depends_on_function(thermal.q.dependency_functions, feenox.pde.solution[0]);
137137

138-
feenox.pde.has_mass = (feenox_var_value(feenox_special_var(end_time)) > 0) && (feenox.pde.transient_type != transient_type_quasistatic);
138+
feenox.pde.has_mass = (feenox_var_value(feenox_special_var(end_time)) > 0) && (feenox.pde.transient_type != transient_type_quasistatic);
139139
if (feenox.pde.has_mass) {
140140
///pr_thermal+kappa+usage kappa
141141
///pr_thermal+kappa+description Thermal diffusivity in units of area per unit of time.

tests/.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*.trs
44
*.last
55
*.m
6+
*.pvd
67
tmp.*
78
mesh2d.msh
89
square-centered.msh
@@ -84,5 +85,6 @@ wilson-2d-*.vt*
8485
hex8-ldef.dat
8586
*.frd
8687
*.sta
87-
hex8-ldef.vtk
88+
hex8-ldef.vt*
8889
spooles.out
90+
beam*.vt*
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
PROBLEM mechanical QUASISTATIC
2+
READ_MESH beam-cantilever-tet4.msh
3+
4+
ldef = 1
5+
end_time = 1
6+
dt_0 = 0.01
7+
8+
E = 100000
9+
nu = 0.3
10+
11+
BC left fixed
12+
BC right tz=-25*t
13+
14+
SOLVE_PROBLEM
15+
16+
IF done
17+
PRINT w(0.5,-0.25,+0.01)+0.016062
18+
ENDIF
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
PROBLEM mechanical QUASISTATIC
2+
READ_MESH beam-cantilever-tet4.msh
3+
4+
ldef = 1
5+
end_time = 1
6+
dt_0 = 1
7+
8+
E = 100000
9+
nu = 0.3
10+
11+
BC left fixed
12+
BC right tz=-25*t
13+
14+
SOLVE_PROBLEM
15+
16+
IF done
17+
PRINT w(0.5,-0.25,+0.01)+0.016062
18+
ENDIF

0 commit comments

Comments
 (0)