// StrDistMatrix returns a string representation of Dist matrix func (o *Graph) StrDistMatrix() (l string) { nv := len(o.Dist) maxlen := 0 for i := 0; i < nv; i++ { for j := 0; j < nv; j++ { if o.Dist[i][j] < GRAPH_INF { maxlen = utl.Imax(maxlen, len(io.Sf("%g", o.Dist[i][j]))) } } } maxlen = utl.Imax(3, maxlen) fmts := io.Sf("%%%ds", maxlen+1) fmtn := io.Sf("%%%dg", maxlen+1) for i := 0; i < nv; i++ { for j := 0; j < nv; j++ { if o.Dist[i][j] < GRAPH_INF { l += io.Sf(fmtn, o.Dist[i][j]) } else { l += io.Sf(fmts, "∞") } } l += "\n" } return }
// GetShapeNurbs returns a shape structure based on NURBS // Note: span are the local ids of control points in NURBS defining elements // Note: FaceLocalVerts does not work for internal surfaces; only those @ boundaries func GetShapeNurbs(nurbs *gm.Nurbs, nrbfaces []*gm.Nurbs, span []int) (o *Shape) { // basic data o = new(Shape) o.Type = "nurbs" o.FaceType = "nurbs" o.Gndim = nurbs.Gnd() switch o.Gndim { case 1: o.BasicType = "lin2" case 2: o.BasicType = "qua4" case 3: o.BasicType = "hex8" } o.Nverts = nurbs.GetElemNumBasis() o.VtkCode = VTK_POLY_VERTEX o.Func = o.NurbsFunc o.FaceFunc = o.NurbsFaceFunc o.Nurbs = nurbs o.Span = span o.Ibasis = o.Nurbs.IndBasis(o.Span) o.U = make([]float64, o.Gndim) // faces basic data nfaces := 2 * o.Gndim o.FaceLocalVerts = nurbs.ElemBryLocalInds() if o.Gndim == 3 { o.NurbsFaces = nrbfaces o.SpanFace = [][]int{ span[0:2], span[0:2], span[2:4], span[2:4], span[4:6], span[4:6], } o.FaceFlip = []bool{false, true, false, true, false, true} // => point to the inside } else { o.NurbsFaces = []*gm.Nurbs{nrbfaces[2], nrbfaces[1], nrbfaces[3], nrbfaces[0]} o.SpanFace = [][]int{span[0:2], span[2:4], span[0:2], span[2:4]} o.FaceFlip = []bool{false, false, true, true} // => point to the inside } o.IbasisFace = make([][]int, nfaces) for idxface, face := range o.NurbsFaces { o.IbasisFace[idxface] = face.IndBasis(o.SpanFace[idxface]) if idxface == 0 { o.FaceNvertsMax = len(o.IbasisFace[idxface]) } else { o.FaceNvertsMax = utl.Imax(o.FaceNvertsMax, len(o.IbasisFace[idxface])) } } // allocate stracthpad variables o.init_scratchpad() return }
// GetStringSizes returns the sizes of strings representing each gene type // sizes -- [6][...] sizes of strings for {int, flt, string, byte, bytes, func} func (o *Individual) GetStringSizes() (sizes [][]int) { sizes = make([][]int, 6) if o.Ints != nil { sizes[0] = make([]int, len(o.Ints)) for i, x := range o.Ints { sizes[0][i] = utl.Imax(sizes[0][i], len(io.Sf("%v", x))) } } if o.Floats != nil { sizes[1] = make([]int, o.Nfltgenes) for i := 0; i < o.Nfltgenes; i++ { x := o.Floats[i] if o.Nbases > 1 { x = 0 for j := 0; j < o.Nbases; j++ { x += o.Floats[i*o.Nbases+j] } } sizes[1][i] = utl.Imax(sizes[1][i], len(io.Sf("%v", x))) } } if o.Strings != nil { sizes[2] = make([]int, len(o.Strings)) for i, x := range o.Strings { sizes[2][i] = utl.Imax(sizes[2][i], len(io.Sf("%v", x))) } } if o.Keys != nil { sizes[3] = make([]int, len(o.Keys)) for i, x := range o.Keys { sizes[3][i] = utl.Imax(sizes[3][i], len(io.Sf("%v", x))) } } if o.Bytes != nil { sizes[4] = make([]int, len(o.Bytes)) for i, x := range o.Bytes { sizes[4][i] = utl.Imax(sizes[4][i], len(io.Sf("%v", string(x)))) } } if o.Funcs != nil { sizes[5] = make([]int, len(o.Funcs)) for i, x := range o.Funcs { sizes[5][i] = utl.Imax(sizes[5][i], len(io.Sf("%v", x(o)))) } } return }
func main() { // catch errors defer func() { if err := recover(); err != nil { io.PfRed("ERROR: %v\n", err) } }() // input data mshfn, fnkey := io.ArgToFilename(0, "data/sgm57", ".msh", true) // old mesh var old OldMesh // read file b, err := io.ReadFile(mshfn) if err != nil { chk.Panic("%v", err) } // decode err = json.Unmarshal(b, &old) if err != nil { chk.Panic("%v", err) } // verts: find largest strings var ndim int L := make([]int, 5) for _, v := range old.Verts { L[0] = utl.Imax(L[0], len(io.Sf("%d", v.Id))) L[1] = utl.Imax(L[1], len(io.Sf("%d", v.Tag))) for j, x := range v.C { L[2+j] = utl.Imax(L[2+j], len(io.Sf("%g", x))) } ndim = len(v.C) } S := make([]string, 5) for i, l := range L { S[i] = io.Sf("%d", l) } // write vertices buf := new(bytes.Buffer) io.Ff(buf, "{\n \"verts\":[\n") for i, v := range old.Verts { if i > 0 { io.Ff(buf, ",\n") } io.Ff(buf, " {\"i\":%"+S[0]+"d, \"t\":%"+S[1]+"d, \"x\":[", v.Id, v.Tag) for j, x := range v.C { if j > 0 { io.Ff(buf, ", ") } io.Ff(buf, "%"+S[2+j]+"g", x) } io.Ff(buf, "] }") } // cells: find largest strings n := 30 L = make([]int, n*2) for _, c := range old.Cells { L[0] = utl.Imax(L[0], len(io.Sf("%d", c.Id))) L[1] = utl.Imax(L[1], len(io.Sf("%d", c.Tag))) L[2] = utl.Imax(L[2], len(io.Sf("%d", c.Part))) for j, v := range c.Verts { L[3+j] = utl.Imax(L[3+j], len(io.Sf("%d", v))) } } S = make([]string, n*2) for i, l := range L { S[i] = io.Sf("%d", l) } io.Ff(buf, "\n ],") // write cells io.Ff(buf, "\n \"cells\":[\n") for i, c := range old.Cells { if i > 0 { io.Ff(buf, ",\n") } io.Ff(buf, " {\"i\":%"+S[0]+"d, \"t\":%"+S[1]+"d, \"p\":%"+S[2]+"d, \"y\":%q, \"v\":[", c.Id, c.Tag, c.Part, c.Type) for j, v := range c.Verts { if j > 0 { io.Ff(buf, ", ") } io.Ff(buf, "%"+S[3+j]+"d", v) } io.Ff(buf, "]") if len(c.FTags) > 0 { io.Ff(buf, ", ") if ndim == 2 { io.Ff(buf, "\"et\":[") } else { io.Ff(buf, "\"ft\":[") } for j, t := range c.FTags { if j > 0 { io.Ff(buf, ", ") } io.Ff(buf, "%d", t) } io.Ff(buf, "]") } io.Ff(buf, " }") } io.Ff(buf, "\n ]\n}") io.WriteFileVD("/tmp/gosl", fnkey+"-new.msh", buf) // check m, err := msh.Read("/tmp/gosl/" + fnkey + "-new.msh") if err != nil { chk.Panic("cannot read new mesh:\n%v", err) } m.Check() }
// Compute computes limits, find non-dominated Pareto fronts, and compute crowd distances func (o *Metrics) Compute(sols []*Solution) (nfronts int) { // reset variables and find limits z := o.Fsizes nsol := len(sols) for i, sol := range sols { // reset values sol.Nwins = 0 sol.Nlosses = 0 sol.FrontId = 0 sol.DistCrowd = 0 sol.DistNeigh = INF z[i] = 0 // check oors for j := 0; j < o.prms.Noor; j++ { if math.IsNaN(sol.Oor[j]) { chk.Panic("NaN found in out-of-range value array\n\txFlt = %v\n\txInt = %v\n\tova = %v\n\toor = %v", sol.Flt, sol.Int, sol.Ova, sol.Oor) } } // ovas range for j := 0; j < o.prms.Nova; j++ { x := sol.Ova[j] if math.IsNaN(x) { chk.Panic("NaN found in objective value array\n\txFlt = %v\n\txInt = %v\n\tova = %v\n\toor = %v", sol.Flt, sol.Int, sol.Ova, sol.Oor) } if i == 0 { o.Omin[j] = x o.Omax[j] = x } else { o.Omin[j] = utl.Min(o.Omin[j], x) o.Omax[j] = utl.Max(o.Omax[j], x) } } // floats range for j := 0; j < o.prms.Nflt; j++ { x := sol.Flt[j] if i == 0 { o.Fmin[j] = x o.Fmax[j] = x } else { o.Fmin[j] = utl.Min(o.Fmin[j], x) o.Fmax[j] = utl.Max(o.Fmax[j], x) } } // ints range for j := 0; j < o.prms.Nint; j++ { x := sol.Int[j] if i == 0 { o.Imin[j] = x o.Imax[j] = x } else { o.Imin[j] = utl.Imin(o.Imin[j], x) o.Imax[j] = utl.Imax(o.Imax[j], x) } } } // compute neighbour distance for i := 0; i < nsol; i++ { A := sols[i] for j := i + 1; j < nsol; j++ { B := sols[j] o.closest(A, B) } } // skip if single-objective problem if o.prms.Nova < 2 { return } // compute wins/losses data for i := 0; i < nsol; i++ { A := sols[i] for j := i + 1; j < nsol; j++ { B := sols[j] A_win, B_win := A.Compare(B) if A_win { A.WinOver[A.Nwins] = B A.Nwins++ B.Nlosses++ } if B_win { B.WinOver[B.Nwins] = A B.Nwins++ A.Nlosses++ } } } // first front for _, sol := range sols { if sol.Nlosses == 0 { o.Fronts[0][z[0]] = sol z[0]++ } } // next fronts for r, front := range o.Fronts { if z[r] == 0 { break } s := r + 1 nfronts++ for i := 0; i < z[r]; i++ { A := front[i] for j := 0; j < A.Nwins; j++ { B := A.WinOver[j] B.Nlosses-- if B.Nlosses == 0 { // B belongs to next front B.FrontId = s o.Fronts[s][z[s]] = B z[s]++ } } } } // crowd distances for r := 0; r < nfronts; r++ { l, m := z[r], z[r]-1 if l == 1 { o.Fronts[r][0].DistCrowd = -1 continue } F := o.Fronts[r][:l] for j := 0; j < o.prms.Nova; j++ { SortByOva(F, j) δ := o.Omax[j] - o.Omin[j] + 1e-15 F[0].DistCrowd = INF F[m].DistCrowd = INF for i := 1; i < m; i++ { F[i].DistCrowd += ((F[i].Ova[j] - F[i-1].Ova[j]) / δ) * ((F[i+1].Ova[j] - F[i].Ova[j]) / δ) } } } return }
// Output generates a nice table with population data func (o Population) Output(C *ConfParams) (buf *bytes.Buffer) { // check if len(o) < 1 { return } // compute sizes and generate formats list if C.NumFmts == nil { sizes := make([][]int, 6) for _, ind := range o { sz := ind.GetStringSizes() for i := 0; i < 6; i++ { if len(sizes[i]) == 0 { sizes[i] = make([]int, len(sz[i])) } for j, s := range sz[i] { sizes[i][j] = utl.Imax(sizes[i][j], s) } } } name := []string{"int", "flt", "str", "key", "byt", "fun"} C.NumFmts = make(map[string][]string) for i, str := range []string{"d", "g", "s", "x", "s", "s"} { C.NumFmts[name[i]] = make([]string, len(sizes[i])) for j, sz := range sizes[i] { C.NumFmts[name[i]][j] = io.Sf("%%%d%s", sz+1, str) } } } // compute sizes of header items nova := len(o[0].Ovas) noor := len(o[0].Oors) szova, szoor, szdem := make([]int, nova), make([]int, noor), 0 for k, ind := range o { if C.ShowNinds > 0 && k >= C.ShowNinds { break } for i := 0; i < nova; i++ { szova[i] = utl.Imax(szova[i], len(io.Sf("%g", ind.Ovas[i]))) } if C.ShowOor { for i := 0; i < noor; i++ { szoor[i] = utl.Imax(szoor[i], len(io.Sf("%g", ind.Oors[i]))) } } szdem = utl.Imax(szdem, len(io.Sf("%g", ind.Demerit))) } for i := 0; i < nova; i++ { szova[i] = utl.Imax(szova[i], 5) // 5 ==> len("Ova##") } if C.ShowOor { for i := 0; i < noor; i++ { szoor[i] = utl.Imax(szoor[i], 5) // 5 ==> len("Oor####") } } szdem = utl.Imax(szdem, 7) // 7 ==> len("Demerit") // print individuals fmtova := make([]string, nova) fmtoor := make([]string, noor) for i := 0; i < nova; i++ { fmtova[i] = io.Sf("%%%d", szova[i]+1) } if C.ShowOor { for i := 0; i < noor; i++ { fmtoor[i] = io.Sf("%%%d", szoor[i]+1) } } fmtdem := io.Sf("%%%d", szdem+1) line, sza, szb := "", 0, 0 first := true for i, ind := range o { if C.ShowNinds > 0 && i >= C.ShowNinds { break } stra := "" for j := 0; j < nova; j++ { stra += io.Sf(fmtova[j]+"g", ind.Ovas[j]) } if C.ShowOor { for j := 0; j < noor; j++ { if ind.Oors[j] > 0 { stra += io.Sf(fmtoor[j]+"g", ind.Oors[j]) } else { stra += io.Sf(fmtoor[j]+"s", "n/a") } } } else { unfeasible := false for j := 0; j < noor; j++ { if ind.Oors[j] > 0 { unfeasible = true } } if unfeasible { stra += " unfe." } else { stra += " " } } if C.ShowDem { stra += io.Sf(fmtdem+"g", ind.Demerit) + " " } strb := ind.Output(C.NumFmts, C.ShowBases) line += stra + strb + "\n" if first { sza, szb = len(stra), len(strb) first = false } } // write to buffer fmtgenes := io.Sf("%%%d.%ds\n", szb, szb) n := sza + szb buf = new(bytes.Buffer) io.Ff(buf, io.StrThickLine(n)) for i := 0; i < nova; i++ { io.Ff(buf, fmtova[i]+"s", io.Sf("Ova%d", i)) } if C.ShowOor { for i := 0; i < noor; i++ { io.Ff(buf, fmtoor[i]+"s", io.Sf("Oor%d", i)) } } else { io.Ff(buf, " check") } if C.ShowDem { io.Ff(buf, fmtdem+"s ", "Demerit") } io.Ff(buf, fmtgenes, "Genes") io.Ff(buf, io.StrThinLine(n)) io.Ff(buf, line) io.Ff(buf, io.StrThickLine(n)) return }
// GetIps returns a set of integration points // If the number (nips) of integration points is zero, it returns a default set func (o *Shape) GetIps(nips, nipf int) (ips, ipf []Ipoint, err error) { // NURBS if o.Type == "nurbs" { maxord := o.Nurbs.Ord(0) for i := 1; i < o.Gndim; i++ { maxord = utl.Imax(maxord, o.Nurbs.Ord(i)) } switch o.Gndim { case 1: switch maxord { case 1: ips = ips_lin_2 case 2: ips = ips_lin_3 default: err = chk.Err("1D NURBS: cannot get integration points with maxord=%d", maxord) } case 2: switch maxord { case 1: ips = ips_qua_4 ipf = ips_lin_2 case 2: ips = ips_qua_9 ipf = ips_lin_3 default: err = chk.Err("2D NURBS: cannot get integration points with maxord=%d", maxord) } case 3: switch maxord { case 1: ips = ips_hex_8 ipf = ips_qua_4 case 2: ips = ips_hex_27 ipf = ips_qua_9 default: err = chk.Err("3D NURBS: cannot get integration points with maxord=%d", maxord) } } return } // Lagrangean elements var ok bool key := io.Sf("%s_%d", o.Type, nips) ips, ok = ipsfactory[key] if !ok { err = chk.Err("cannot find integration point set for geometry type = %s and nips = %d\n", o.Type, nips) return } if o.Gndim > 1 { key = io.Sf("%s_%d", o.FaceType, nipf) ipf, ok = ipsfactory[key] if !ok { err = chk.Err("cannot find (face) integration point set for geometry type = %s and nips = %d\n", o.FaceType, nipf) return } } return }
// Plot runs the plot generation (basic set) func (o *Plotter) Plot(keys []string, res []*State, sts [][]float64, first, last bool) { // auxiliary variables nr := utl.Imax(len(res), len(sts)) if nr < 1 { return } x := make([]float64, nr) y := make([]float64, nr) o.P = make([]float64, nr) o.Q = make([]float64, nr) o.W = make([]float64, nr) o.Ev = make([]float64, nr) o.Ed = make([]float64, nr) // compute invariants for i := 0; i < len(res); i++ { if len(res[i].Sig) < 4 { chk.Panic("number of stress components is incorrect: %d", len(res[i].Sig)) } o.P[i], o.Q[i], o.W[i] = tsr.M_pqw(res[i].Sig) } nsig := len(res[0].Sig) devε := make([]float64, nsig) for i := 0; i < len(sts); i++ { if len(sts[i]) < 4 { chk.Panic("number of strain components is incorrect: %d", len(sts[i])) } _, o.Ev[i], o.Ed[i] = tsr.M_devε(devε, sts[i]) } // clear previous figure if first { plt.Clf() plt.SplotGap(0.35, 0.35) if o.Hspace > 0 { plt.SetHspace(o.Hspace) } if o.Vspace > 0 { plt.SetVspace(o.Vspace) } } // number of points for contour if o.NptsPq < 2 { o.NptsPq = 61 } if o.NptsOct < 2 { o.NptsOct = 41 } if o.NptsSig < 2 { o.NptsSig = 41 } // subplot variables o.Pidx = 1 o.Ncol, o.Nrow = utl.BestSquare(len(keys)) if len(keys) == 2 { o.Ncol, o.Nrow = 1, 2 } if len(keys) == 3 { o.Ncol, o.Nrow = 1, 3 } // do plot for _, key := range keys { o.Subplot() switch key { case "ed,q": o.QdivP = false o.Plot_ed_q(x, y, res, sts, last) case "ed,q/p": o.QdivP = true o.Plot_ed_q(x, y, res, sts, last) case "p,q": o.WithYs = false o.Plot_p_q(x, y, res, sts, last) case "p,q,ys": o.WithYs = true o.Plot_p_q(x, y, res, sts, last) case "ed,ev": o.Plot_ed_ev(x, y, res, sts, last) case "p,ev": o.LogP = false o.Plot_p_ev(x, y, res, sts, last) case "log(p),ev": o.LogP = true o.Plot_p_ev(x, y, res, sts, last) case "i,f": o.Plot_i_f(x, y, res, sts, last) case "i,alp": o.Plot_i_alp(x, y, res, sts, last) case "Dgam,f": o.Plot_Dgam_f(x, y, res, sts, last) case "oct": o.WithYs = false o.Plot_oct(x, y, res, sts, last) case "oct,ys": o.WithYs = true o.Plot_oct(x, y, res, sts, last) case "s3,s1": o.WithYs = false o.Plot_s3_s1(x, y, res, sts, last) case "s3,s1,ys": o.WithYs = true o.Plot_s3_s1(x, y, res, sts, last) case "empty": continue default: chk.Panic("cannot handle key=%q", key) } if o.Split && last { o.Save("_", key) } } // save figure if !o.Split && last { o.Save("", "") } }