Skip to content

PDE project 4 - #81

Open
chuckdotsvg wants to merge 17 commits into
michelebucelli:mainfrom
chuckdotsvg:main
Open

PDE project 4#81
chuckdotsvg wants to merge 17 commits into
michelebucelli:mainfrom
chuckdotsvg:main

Conversation

@chuckdotsvg

Copy link
Copy Markdown

this is our delivery of project 4

KarimOdisseo00 and others added 17 commits July 8, 2026 23:55
… di Blocco Numerico e Accommodation)

Riscritto IonicModel.hpp per renderlo matematicamente conforme alle equazioni 
del paper originale (Bueno-Orovio, Cherry, Fenton - JTB 2008). 
La versione precedente bloccava la propagazione dell'onda a pochi millimetri 
dall'innesco su griglie h >= 0.2mm a causa di gravi errori di trascrizione.

Dettaglio dei bug risolti:
1. Errore funzioni Heaviside (Il "Misfire" biologico): 
   Il calcolo della derivata temporale del gate V utilizzava erroneamente 
   la soglia di pre-allarme theta_v_minus (0.006) invece della vera 
   soglia di attivazione theta_v (0.3). Il "piede" dell'onda diffuso 
   dalla FEM innescava prematuramente la chiusura del gate V. 
   Quando il voltaggio raggiungeva la soglia reale, il combustibile 
   cellulare (V) era già esaurito (Accommodation), impedendo alla 
   corrente J_fi di propagare il segnale. Stessa correzione applicata a W e S 
   usando la corretta soglia theta_w (0.13).

2. Parametri errati: 
   Sistemati tau_so1 e tau_w_inf con i valori esatti del Set Epicardico 
   (Tabella 1 del paper).

Questa correzione alla cinetica del modello ionico, accoppiata al 
Mass Lumping (diagonalizzazione della matrice di massa e del RHS 
in CardiacProblem.cpp), risolve definitivamente la dispersione 
e l'emorragia di energia. 
L'onda ora propaga correttamente su maglie a bassa risoluzione spaziale, 
consentendo l'uso del dispositivo in modalità HPC portatile (MPI-ready).
1) PARAMETRI: Modificati i parametri della simulazione per fare benchmarking in concordanza con il paper (h=0.2mm e final_time=40ms). Questo è necessario perchè con h=0.5 la risoluzione della mesh generata è troppo grossolana per i transienti, tuttavia bisogna lavorare per ottenere risultati accettabili anche con h=0.5mm. Imporre il final_time=40ms è necessario per vedere la propagazione raggiungere la prossimità del punto opposto (il paper dichiara circa 43ms) che infatti non viene raggiunto ancora.

2) LHS (Mass Lumping sulla matrice): Nel metodo assemble_system() è stato radicalmente cambiato il calcolo della matrice di massa (GRANDE PROBLEMA CHE VIENE TRATTATO NEL BENCHMARKING DEL PAPER ASSEGNATO! SAREBBE INTERESSANTE FARE BENCHMARKING CON SOLUZIONI DIVERSE PER IL CALCOLO DELLA MASS MATRIX (o della sua assenza) p.15). Invece di calcolare l'interazione tra tutti i nodi della cella, la massa viene ora calcolata e aggiunta esclusivamente sulla diagonale principale (cell_matrix(i, i)). 
Utilizzare una matrice di massa "consistente" (l'approccio standard precedente) per problemi di reazione-diffusione rigidi causa oscillazioni numeriche note come "undershoots". Queste oscillazioni generano voltaggi negativi artificiali immediatamente davanti al fronte d'onda. Concentrando la massa solo sui nodi (diagonalizzazione o Mass Lumping), si eliminano matematicamente questi voltaggi negativi, prevenendo la progressiva perdita di energia che causava possibile blocco dell'onda.

3) RHS: La variabile per memorizzare i valori del passo precedente è stata realizzata usando variabile della libreria dealii (dealii::Vector). Inoltre, invece di interpolare i valori ai punti di quadratura, i valori vengono estratti esattamente ai nodi (get_dof_values). Il termine noto di dx viene poi costruito moltiplicando la massa "lumpata" per il valore esatto al nodo: [cell_rhs(i) += lumped_mass_q * local_solution_values(i)].
Nell'analisi agli elementi finiti, se si applica la diagonalizzazione della massa alla matrice di sinistra (LHS), è matematicamente obbligatorio applicare lo stesso identico trattamento al vettore di destra (RHS). Mischiare un LHS diagonalizzato con un RHS consistente avrebbe introdotto gravi artefatti algebrici, corrompendo irrimediabilmente la soluzione.
CardiacProblem.cpp Fix: Risolto mancanza
1) PARAMETRI: Modificati i parametri della simulazione per fare benchmarking in concordanza con il paper (h=0.2mm e final_time=40ms). Questo è necessario perchè con h=0.5 la risoluzione della mesh generata è troppo grossolana per i transienti, tuttavia bisogna lavorare per ottenere risultati accettabili anche con h=0.5mm. Imporre il final_time=40ms è necessario per vedere la propagazione raggiungere la prossimità del punto opposto (il paper dichiara circa 43ms) che infatti non viene raggiunto ancora.

2) LHS (Mass Lumping sulla matrice): Nel metodo assemble_system() è stato radicalmente cambiato il calcolo della matrice di massa (GRANDE PROBLEMA CHE VIENE TRATTATO NEL BENCHMARKING DEL PAPER ASSEGNATO! SAREBBE INTERESSANTE FARE BENCHMARKING CON SOLUZIONI DIVERSE PER IL CALCOLO DELLA MASS MATRIX (o della sua assenza) p.15). Invece di calcolare l'interazione tra tutti i nodi della cella, la massa viene ora calcolata e aggiunta esclusivamente sulla diagonale principale (cell_matrix(i, i)). 
Utilizzare una matrice di massa "consistente" (l'approccio standard precedente) per problemi di reazione-diffusione rigidi causa oscillazioni numeriche note come "undershoots". Queste oscillazioni generano voltaggi negativi artificiali immediatamente davanti al fronte d'onda. Concentrando la massa solo sui nodi (diagonalizzazione o Mass Lumping), si eliminano matematicamente questi voltaggi negativi, prevenendo la progressiva perdita di energia che causava possibile blocco dell'onda.

3) RHS: La variabile per memorizzare i valori del passo precedente è stata realizzata usando variabile della libreria dealii (dealii::Vector). Inoltre, invece di interpolare i valori ai punti di quadratura, i valori vengono estratti esattamente ai nodi (get_dof_values). Il termine noto di dx viene poi costruito moltiplicando la massa "lumpata" per il valore esatto al nodo: [cell_rhs(i) += lumped_mass_q * local_solution_values(i)].
Nell'analisi agli elementi finiti, se si applica la diagonalizzazione della massa alla matrice di sinistra (LHS), è matematicamente obbligatorio applicare lo stesso identico trattamento al vettore di destra (RHS). Mischiare un LHS diagonalizzato con un RHS consistente avrebbe introdotto gravi artefatti algebrici, corrompendo irrimediabilmente la soluzione.
CardiacProblem.cpp Fix: Risolto mancanza
1) PARAMETRI: Modificati i parametri della simulazione per fare benchmarking in concordanza con il paper (h=0.2mm e final_time=40ms). Questo è necessario perchè con h=0.5 la risoluzione della mesh generata è troppo grossolana per i transienti, tuttavia bisogna lavorare per ottenere risultati accettabili anche con h=0.5mm. Imporre il final_time=40ms è necessario per vedere la propagazione raggiungere la prossimità del punto opposto (il paper dichiara circa 43ms) che infatti non viene raggiunto ancora.

2) LHS (Mass Lumping sulla matrice): Nel metodo assemble_system() è stato radicalmente cambiato il calcolo della matrice di massa (GRANDE PROBLEMA CHE VIENE TRATTATO NEL BENCHMARKING DEL PAPER ASSEGNATO! SAREBBE INTERESSANTE FARE BENCHMARKING CON SOLUZIONI DIVERSE PER IL CALCOLO DELLA MASS MATRIX (o della sua assenza) p.15). Invece di calcolare l'interazione tra tutti i nodi della cella, la massa viene ora calcolata e aggiunta esclusivamente sulla diagonale principale (cell_matrix(i, i)). 
Utilizzare una matrice di massa "consistente" (l'approccio standard precedente) per problemi di reazione-diffusione rigidi causa oscillazioni numeriche note come "undershoots". Queste oscillazioni generano voltaggi negativi artificiali immediatamente davanti al fronte d'onda. Concentrando la massa solo sui nodi (diagonalizzazione o Mass Lumping), si eliminano matematicamente questi voltaggi negativi, prevenendo la progressiva perdita di energia che causava possibile blocco dell'onda.

3) RHS: La variabile per memorizzare i valori del passo precedente è stata realizzata usando variabile della libreria dealii (dealii::Vector). Inoltre, invece di interpolare i valori ai punti di quadratura, i valori vengono estratti esattamente ai nodi (get_dof_values). Il termine noto di dx viene poi costruito moltiplicando la massa "lumpata" per il valore esatto al nodo: [cell_rhs(i) += lumped_mass_q * local_solution_values(i)].
Nell'analisi agli elementi finiti, se si applica la diagonalizzazione della massa alla matrice di sinistra (LHS), è matematicamente obbligatorio applicare lo stesso identico trattamento al vettore di destra (RHS). Mischiare un LHS diagonalizzato con un RHS consistente avrebbe introdotto gravi artefatti algebrici, corrompendo irrimediabilmente la soluzione.
Risolto definitivamente il bug macroscopico che causava il crollo artificiale 
del potenziale transmembrana (V=0) lungo le interfacce di partizionamento 
geometrico dei 4 sottodomini MPI durante l'esecuzione parallela. 

Dettaglio dell'analisi tecnica e risoluzione della regressione:
L'utilizzo precedente della classe ausiliaria DynamicSparsityPattern di deal.II 
per l'inizializzazione delle strutture lineari causava un troncamento silente 
delle informazioni topologiche fuori diagonale (off-diagonal sub-matrices). 
Durante il reinit delle matrici di Trilinos, venivano ignorate le colonne di 
accoppiamento inter-processore relative ai nodi ghost condivisi. Di conseguenza, 
i termini di conducibilità spaziale generati dal Laplaciano cross-boundary 
venivano rigettati in memoria RAM durante l'assembly, azzerando i flussi diffusivi 
tra i core e isolando matematicamente i singoli sottodomini.

Il problema è stato eradicato inizializzando in modo nativo l'oggetto 
TrilinosWrappers::SparsityPattern legandolo direttamente all'IndexSet dei DoF owned 
e al comunicatore globale MPI_COMM_WORLD. L'aggiunta del metodo .compress() ha 
sincronizzato correttamente le tabelle di allocazione dei nodi ghost di bordo 
aprendo i canali di scambio dell'algebra parallela. L'integrazione del 
precondizionatore Jacobi (scalatura diagonale pura), ideale per una matrice 
fortemente dominata dalla massa diagonale (Mass Lumping con dt=0.001), ha garantito 
la stabilità e la perfetta continuità del fronte d'onda, stabilizzando il tempo di 
computazione ottimale a 452 secondi complessivi.

TODO:
- Pianificare e strutturare una sessione intensiva di benchmarking comparativo.
- Re-implementare provvisoriamente i vecchi precondizionatori (AMG, ILU Block-Jacobi) 
  e testare nuove metriche di scalabilità lineare per mappare formalmente l'overhead 
  di comunicazione di rete al variare della risoluzione spaziale (h) e del numero di core.
Non ha prodotto i risultati sperati tuttavia si è avuto uno speedup di circa x1.26.
La tecnica è stata applicata solo a ODE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants