#!/usr/bin/env python
from assignment8 import StressStrainConverter
import numpy as np
import scipy.integrate

from PyTrilinos import Epetra

class EpetraParallelToughness(StressStrainConverter):

    def __init__(self, filename, comm):
        super().__init__(filename)

        self.comm = comm
        self.rank = comm.MyPID()
        self.size = comm.NumProc()

        if self.rank == 0:
            self.convert_to_true_stress_and_strain()
        else:
            self.true_stress = np.array([], dtype=np.double)
            self.true_strain = np.array([], dtype=np.double)
            
    def parsing(self):
        gsl = np.array([len(self.true_stress)])
        gsl2 = np.array([len(self.true_strain)])
        self.comm.Broadcast(gsl,0)
        self.comm.Broadcast(gsl2,0)
        if self.rank == 0:
            mylength = len(self.true_stress)
            grab_elements = 1
            grab = 0
        else:
            mylength = 0
            grab_elements = 1
            grab = 0
        unbalanced_strain_map = Epetra.Map(gsl2[0],mylength,0,self.comm)            
        unbalanced_stress_map = Epetra.Map(gsl[0],mylength,0,self.comm)
        balanced_strain_map   = Epetra.Map(gsl2[0],0,self.comm)
        balanced_stress_map   = Epetra.Map(gsl[0],0,self.comm)
        unbalanced_strain = Epetra.Vector(Epetra.Copy,unbalanced_strain_map,self.true_strain)
        unbalanced_stress = Epetra.Vector(Epetra.Copy,unbalanced_stress_map,self.true_stress)
        balanced_strain = Epetra.Vector(balanced_strain_map)
        balanced_stress = Epetra.Vector(balanced_stress_map)
        strain_importer = Epetra.Import(balanced_strain_map, unbalanced_strain_map)
        stress_importer = Epetra.Import(balanced_stress_map, unbalanced_stress_map)
        balanced_strain.Import(unbalanced_strain,strain_importer,Epetra.Insert)
        balanced_stress.Import(unbalanced_stress,stress_importer,Epetra.Insert)        
        grab_strain_map = Epetra.Map(self.comm,SumAll(grab_elements),0,self.comm)
        grab_stress_map = Epetra.Map(self.comm,SumAll(grab_elements),0,self.comm)
        grab_strain_vector = Epetra.Vector(grab_strain_map,balanced_strain[grab])
        grab_stress_vector = Epetra.Vector(grab_stress_map,balanced_stress[grab])        
        gathered_grab_strain_vector = self.comm.GatherAll(grab_strain_vector)
        gathered_grab_stress_vector = self.comm.GatherAll(grab_stress_vector)
        for i in range(self.size-1):
            if i == self.rank:
                balanced_strain = np.append(balanced_strain, gathered_grab_strain_vector[i-1])
                balanced_stress = np.append(balanced_stress, gathered_grab_stress_vector[i-1])             
        self.true_strain = balanced_strain
        self.true_stress = balanced_stress
        
        
        
        
        
        
        
        
        return
    
    
    def compute_toughness(self):
        
        my_toughness = scipy.integrate.trapz(self.true_stress, self.true_strain)

        return self.comm.SumAll(my_toughness)


if __name__ == "__main__":

    from PyTrilinos import Epetra

    comm = Epetra.PyComm()

    T = EpetraParallelToughness('data.dat', comm)

    if comm.MyPID() == 0:
        print(T.compute_toughness())

#!/usr/bin/env python
from assignment8 import StressStrainConverter
import numpy as np
import scipy.integrate

from PyTrilinos import Epetra

class EpetraParallelToughness(StressStrainConverter):

    def __init__(self, filename, comm):
        super().__init__(filename)

        self.comm = comm
        self.rank = comm.MyPID()
        self.size = comm.NumProc()

        if self.rank == 0:
            self.convert_to_true_stress_and_strain()
        else:
            self.true_stress = np.array([], dtype=np.double)
            self.true_strain = np.array([], dtype=np.double)
            
    def parsing(self):
        gsl = np.array([len(self.true_stress)])
        gsl2 = np.array([len(self.true_strain)])
        self.comm.Broadcast(gsl,0)
        self.comm.Broadcast(gsl2,0)
        if self.rank == 0:
            mylength = len(self.true_stress)
            grab_elements = 1
            grab = 0
        else:
            mylength = 0
            grab_elements = 1
            grab = 0
        unbalanced_strain_map = Epetra.Map(gsl2[0],mylength,0,self.comm)            
        unbalanced_stress_map = Epetra.Map(gsl[0],mylength,0,self.comm)
        balanced_strain_map   = Epetra.Map(gsl2[0],0,self.comm)
        balanced_stress_map   = Epetra.Map(gsl[0],0,self.comm)
        unbalanced_strain = Epetra.Vector(Epetra.Copy,unbalanced_strain_map,self.true_strain)
        unbalanced_stress = Epetra.Vector(Epetra.Copy,unbalanced_stress_map,self.true_stress)
        balanced_strain = Epetra.Vector(balanced_strain_map)
        balanced_stress = Epetra.Vector(balanced_stress_map)
        strain_importer = Epetra.Import(balanced_strain_map, unbalanced_strain_map)
        stress_importer = Epetra.Import(balanced_stress_map, unbalanced_stress_map)
        balanced_strain.Import(unbalanced_strain,strain_importer,Epetra.Insert)
        balanced_stress.Import(unbalanced_stress,stress_importer,Epetra.Insert)        
        grab_strain_map = Epetra.Map(self.comm,SumAll(grab_elements),0,self.comm)
        grab_stress_map = Epetra.Map(self.comm,SumAll(grab_elements),0,self.comm)
        grab_strain_vector = Epetra.Vector(grab_strain_map,balanced_strain[grab])
        grab_stress_vector = Epetra.Vector(grab_stress_map,balanced_stress[grab])        
        gathered_grab_strain_vector = self.comm.GatherAll(grab_strain_vector)
        gathered_grab_stress_vector = self.comm.GatherAll(grab_stress_vector)
        for i in range(self.size-1):
            if i == self.rank:
                balanced_strain = np.append(balanced_strain, gathered_grab_strain_vector[i-1])
                balanced_stress = np.append(balanced_stress, gathered_grab_stress_vector[i-1])             
        self.true_strain = balanced_strain
        self.true_stress = balanced_stress
        
        
        
        
        
        
        
        
        return
    
    
    def compute_toughness(self):
        
        my_toughness = scipy.integrate.trapz(self.true_stress, self.true_strain)

        return self.comm.SumAll(my_toughness)


if __name__ == "__main__":

    from PyTrilinos import Epetra

    comm = Epetra.PyComm()

    T = EpetraParallelToughness('data.dat', comm)

    if comm.MyPID() == 0:
        print(T.compute_toughness())

#!/usr/bin/env python