Skip to content

Commit

Permalink
Update NewtonKrylov.Solve signature (#20)
Browse files Browse the repository at this point in the history
This commit updates the NewtonKrylov.Solve method to propagate
error when max iterations are reached and there is no convergence.

resolves #19
  • Loading branch information
ichantzaras authored Jul 20, 2024
1 parent 6e73e2d commit 74dfa53
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
10 changes: 8 additions & 2 deletions examples/burger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/csv"
"flag"
"fmt"
"log"
"math"
"os"

Expand Down Expand Up @@ -51,10 +52,15 @@ func main() {
if err != nil {
panic(err)
}
defer csvfile.Close()

csvwriter := csv.NewWriter(csvfile)
for i := 0; i < *steps; i++ {
copy(uCpy, u)
res := solver.Solve(problem, u)
res, err := solver.Solve(problem, u)
if err != nil {
log.Fatal(err)
}
copy(u, res.X)

row := make([]string, len(u))
Expand All @@ -64,5 +70,5 @@ func main() {
csvwriter.Write(row)
}
csvwriter.Flush()
csvfile.Close()

}
9 changes: 5 additions & 4 deletions nonlin/newtonKrylov.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ type NewtonKrylov struct {
// Solve solves the non-linear system of equations. The method terminates when
// the inifinity norm of F + the inifinity norm of dx is less than the tolerance.
// dx is the change in x between two sucessive iterations.
func (nk *NewtonKrylov) Solve(p Problem, x []float64) Result {
func (nk *NewtonKrylov) Solve(p Problem, x []float64) (Result, error) {
var deriv DerivativeApprox
switch nk.Stencil {
case 0, 4:
Expand Down Expand Up @@ -85,7 +85,8 @@ func (nk *NewtonKrylov) Solve(p Problem, x []float64) Result {
}
res, err := linsolve.Iterative(&deriv, b, nk.InnerMethod, nk.InnerSettings)
if err != nil {
log.Fatalf("NewtonKrylov: %s\n", err)
log.Printf("[ERROR] NewtonKrylov: %s\n", err)
return Result{}, err
}

if InfNorm(f0)+mat.Norm(res.X, math.Inf(1)) < nk.Tol {
Expand All @@ -94,7 +95,7 @@ func (nk *NewtonKrylov) Solve(p Problem, x []float64) Result {
Converged: true,
MaxF: InfNorm(f0),
F: f0,
}
}, nil
}

// Update x
Expand Down Expand Up @@ -123,5 +124,5 @@ func (nk *NewtonKrylov) Solve(p Problem, x []float64) Result {
Converged: false,
MaxF: InfNorm(f0),
F: f0,
}
}, nil
}
5 changes: 4 additions & 1 deletion nonlin/newtonKrylov_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@ func TestBicStab(t *testing.T) {
p := Problem{
F: test.F,
}
res := solver.Solve(p, test.Init)
res, err := solver.Solve(p, test.Init)
if err != nil {
t.Error(err)
}

if !res.Converged {
t.Errorf("Test #%d did not converged", i)
Expand Down
8 changes: 6 additions & 2 deletions nonlin/nonlin_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package nonlin_test
import (
"fmt"
"math"
"testing"

"github.com/davidkleiven/gononlin/nonlin"
)

func ExampleNewtonKrylov() {
func ExampleNewtonKrylov(t *testing.T) {
// This example shows how one can use NewtonKrylov to solve the
// system of equations
// (x-1)^2*(x - y) = 0
Expand All @@ -32,7 +33,10 @@ func ExampleNewtonKrylov() {
}

x0 := []float64{0.0, 3.0}
res := solver.Solve(problem, x0)
res, err := solver.Solve(problem, x0)
if err != nil {
t.Error(err)
}
fmt.Printf("Root: (x, y) = (%.2f, %.2f)\n", res.X[0], res.X[1])
fmt.Printf("Function value: (%.2f, %.2f)\n", res.F[0], res.F[1])

Expand Down

0 comments on commit 74dfa53

Please sign in to comment.