NYE KODEN MED BESKRIVELSER

 avatar
unknown
python
3 months ago
8.5 kB
11
Indexable
# BESO Python Script — Endringer og kodeforklaring

## Hva ble endret fra originalskriptet?

### Endring 1: Material leses fra din modell (fmtMdb)

**Original:**
```python
mdl.Material('Material01').Elastic(((1.0, 0.3), ))
mdl.HomogeneousSolidSection('sldSec','Material01')
mdl.Material('Material02').Elastic(((0.001**3, 0.3), ))
```
Hardkoder E=1.0 og ν=0.3 — dine materialegenskaper ignoreres fullstendig.

**Endret til:**
```python
myMat = mdl.materials['Material-1']
E  = myMat.elastic.table[0][0]   # Leser E fra din modell (690000 MPa)
nu = myMat.elastic.table[0][1]   # Leser ν fra din modell (0.33)

mdl.Material('Material01').Elastic(((E, nu),))
mdl.Material('Material02').Elastic(((E * 0.001**3, nu),))
```
Nå brukes dine faktiske materialverdier (E=690 000 MPa, ν=0.33 for aluminium).

---

### Endring 2: Guard mot re-kjøring (fmtMdb)

**Lagt til:**
```python
if 'Material01' in mdl.materials.keys(): del mdl.materials['Material01']
if 'Material02' in mdl.materials.keys(): del mdl.materials['Material02']
if 'sldSec' in mdl.sections.keys(): del mdl.sections['sldSec']
if 'voidSec' in mdl.sections.keys(): del mdl.sections['voidSec']
```
Hvis du kjører scriptet to ganger på samme .cae-fil vil Abaqus krasje fordi
Material01/sldSec allerede eksisterer. Denne sjekken sletter dem først hvis de finnes.

---

### Endring 3: Python 3 fix — list() rundt dict.values() (tre steder)

Dette var den kritiske feilen som krasjet koden etter første iterasjon.

**Problem:** Abaqus 2024 bruker Python 3 der dict.values() returnerer en "view",
ikke en liste. Abaqus sin interne sum()-funksjon (importert via `from abaqus import *`)
aksepterte ikke dette.

**Feil (original):**
```python
lo, hi = min(Ae.values()), max(Ae.values())   # KRASJ
if sum(Xe.values())-tv > 0: lo = th           # KRASJ
vh.append(sum(xe.values())/len(xe))           # KRASJ
```

**Fikset:**
```python
lo, hi = min(list(Ae.values())), max(list(Ae.values()))
if sum(list(Xe.values()))-tv > 0: lo = th
vh.append(sum(list(xe.values()))/len(xe))
```
`list()` konverterer view til en vanlig Python-liste som sum()/min()/max() håndterer.

---

## Komplett kodeforklaring

### Importer (linje 1-4)
```python
import math, customKernel
from abaqus import getInput, getInputs
from odbAccess import openOdb
```
- `math` — for sqrt og fabs
- `customKernel` — Abaqus-modul for å lagre egne data i .cae-filen (brukes til å lagre konvergenshistorikk)
- `getInput/getInputs` — viser dialogbokser til brukeren
- `openOdb` — åpner Abaqus output database (.odb) for å lese resultater

---

### fmtMdb — Klargjør modellen (linje 7-27)

Denne funksjonen kjøres én gang før optimaliseringen starter.

```python
def fmtMdb(Mdb):
```

**Hva den gjør:**
1. Leser E og ν fra Material-1
2. Lager to materialer:
   - `Material01` (solid): dine faktiske materialverdier
   - `Material02` (void): E_void = E × 0.001³ ≈ 10⁻⁹ × E (nesten ingenting)
3. Lager to seksjoner: `sldSec` og `voidSec`
4. Starter med å tildele alle elementer til `sldSec` (fullt design)
5. Ber Abaqus om å lagre to output-variabler:
   - `ELEDEN` — element strain energy density (brukes til sensitivitet)
   - `ALLWK` — total ekstern arbeid = compliance (objektfunksjon)

**Hvorfor soft-kill?**
Void-elementer fjernes ikke fysisk, de får bare ekstremt lav stivhet.
Dette gir en glattere optimalisering og unngår singulære stivhetsmatriser.
E_void = E × xmin^p = E × 0.001³ (SIMP-modell med p=3)

---

### FEA — Kjør analyse og hent sensitiviteter (linje 30-38)

```python
def FEA(Iter, Mdb, Xe, Ae):
```

**Hva den gjør per iterasjon:**
1. Lager og kjører en ny Abaqus-job: `Design_Job0`, `Design_Job1`, ...
2. Venter til jobben er ferdig
3. Åpner .odb-filen
4. Leser `ESEDEN` (element strain energy density) for hvert element
5. Beregner sensitivitet: α_e = E_e / x_e
6. Leser total compliance fra `ALLWK`
7. Returnerer compliance som objektfunksjonsverdi

**Sensitiviteten α_e** forteller hvor mye compliance øker hvis elementet fjernes.
Høy α_e = elementet er viktig → behold.
Lav α_e = elementet bidrar lite → kandidat for fjerning.

---

### preFlt — Forbered filterkart (linje 41-56)

```python
def preFlt(Rmin, Elmts, Nds, Fm):
```

Kjøres kun én gang. Beregner for hvert element hvilke naboelementer som
ligger innenfor filterradius Rmin, og vektfaktorene gj for disse.

**Vektfunksjon:** w(r_ej) = max(0, Rmin - r_ej)
Elementer nærmere sentrum vektes høyere.

Resultatet lagres i en dictionary `Fm`:
```
Fm = {
  element_label: [[nabo_label1, nabo_label2, ...], [vekt1, vekt2, ...]],
  ...
}
```

**Hvorfor filtrering?**
Uten filter gir BESO sjakkmønsterinstabilitet — annenhver element
solid/void i et rutemønster som ser optimalt ut matematisk men ikke fysisk.
Filteret glatter sensitivitetene slik at nærliggende elementer påvirker hverandre.

---

### fltAe — Anvend filter (linje 59-63)

```python
def fltAe(Ae, Fm):
```

Bruker filterkartet fra preFlt til å glatte sensitivitetene:

α̃_e = Σ_j (g_j × α_j)

Der summen går over alle naboelementer j innenfor Rmin.
Hvert elements sensitivitet erstattes av et vektet gjennomsnitt av naboene.

---

### BESO — Oppdater designvariabler (linje 66-81)

```python
def BESO(Vf, Xe, Ae, Part, Elmts):
```

**Hva den gjør:**
1. Finner terskelverdien th via biseksjon slik at riktig antall elementer
   blir solid og vi treffer målvolumet Vf
2. Setter Xe[e] = 1.0 (solid) hvis α_e > th, ellers 0.001 (void)
3. Deler alle elementer i to lister: slb (solid) og vlb (void)
4. Tildeler seksjonene sldSec/voidSec til de to element-settene i Abaqus

**Biseksjonsalgoritmen:**
```
lo = min(sensitivitet), hi = max(sensitivitet)
Gjenta:
    th = (lo + hi) / 2
    Tell elementer med α_e > th
    Hvis for mange solide: lo = th
    Hvis for få solide:    hi = th
Inntil (hi-lo)/hi < 0.00001
```

---

### Hovedprogram (linje 84-115)

**Blokk 1: Input**
```python
pars = (('VolFrac:', '0.5'), ('Rmin:', '1'), ('ER:', '0.02'))
vf, rmin, ert = [float(k) ... for k in getInputs(pars)]
mddb = openMdb(getInput('Input CAE file:', default='Testing.cae'))
```
Henter parametere og åpner .cae-filen din.

**Blokk 2: Initialisering**
```python
fmtMdb(mddb)
for el in elmts: xe[el.label] = 1.0   # Start med fullt design
if rmin > 0: preFlt(rmin, elmts, nds, fm)
```
Alle elementer starter som solide (xe=1.0). Filter forberedes.

**Blokk 3: Iterasjonsloop**
```python
while change > 0.001:
    iter += 1
    oh.append(FEA(iter, mddb, xe, ae))          # 1. Kjør FEA
    if rmin > 0: fltAe(ae, fm)                  # 2. Filtrer sensitiviteter
    if iter > 0: ae = dict([(k,(ae[k]+oae[k])/2.0) ...])  # 3. Historisk gjennomsnitt
    oae = ae.copy()
    vh.append(sum(list(xe.values()))/len(xe))   # 4. Registrer volum
    nv = max(vf, vh[-1]*(1.0-ert))              # 5. Beregn målvolum
    BESO(nv, xe, ae, part, elmts)               # 6. Oppdater topologi
    if iter > 10: change = ...                  # 7. Sjekk konvergens
```

Hvert steg i loopen:
1. FEA med nåværende topologi → compliance og sensitiviteter
2. Glatt sensitivitetene med filterkartet
3. Gjennomsnittliggjør med forrige iterasjon (stabiliserer konvergens)
4. Registrer nåværende volumfraksjon
5. Beregn neste målvolum: nv = max(vf, V_current × (1 - ER))
   → Volumet synker med ER=2% per iterasjon inntil det når VolFrac
6. BESO oppdaterer hvilke elementer som er solid/void
7. Etter 10 iterasjoner: sjekk om compliance har stabilisert seg

**Konvergenskriterium:**
```python
change = |Σ(C[k-4:k+1]) - Σ(C[k-9:k-4])| / Σ(C[k-9:k-4])
```
Sammenligner gjennomsnittlig compliance for siste 5 vs forrige 5 iterasjoner.
Stopper når endringen er under 0.1%.

**Blokk 4: Lagre**
```python
mddb.customData.History = {'vol': vh, 'obj': oh}
mddb.saveAs('Final_design.cae')
```
Lagrer konvergenshistorikken og den ferdige topologien.

---

## Oppsummert flyt

```
Testing.cae (ditt originale design)
        ↓
fmtMdb: Les Material-1, lag solid/void seksjoner
        ↓
preFlt: Beregn filterkart (én gang)
        ↓
[For hver iterasjon:]
    FEA → sensitiviteter og compliance
    Filtrer + historisk gjennomsnitt
    BESO: fjern elementer med lav sensitivitet
    Sjekk konvergens
        ↓
Final_design.cae (optimalisert topologi)
```
Editor is loading...
Leave a Comment