static char help[] = "\n"; /* Include "petscmat.h" so that we can use matrices. automatically includes: petsc.h - base PETSc routines petscvec.h - vectors petscsys.h - system routines petscmat.h - matrices petscis.h - index sets petscviewer.h - viewers */ #include #include #include #include "petscmat.h" #include "petsctime.h" #include "petsc_matvec_utils.h" #include "tmm_forcing_utils.h" #include "tmm_external_forcing.h" #include "tmm_external_bc.h" #include "tmm_profile_utils.h" #include "tmm_profile_data.h" #include "tmm_monitor.h" #include "tmm_misfit.h" #include "tmm_main.h" PetscScalar deltaTClock, time0; PetscInt maxSteps, Iter0, writeSteps; PetscInt *gIndices, gLow, gHigh; PetscBool doMisfit = PETSC_FALSE; extern PetscErrorCode forwardStep(PetscScalar tc, PetscInt iLoop, PetscScalar dt, PetscInt numTracers, PetscBool useForcingFromFile, PetscBool useExternalForcing, PetscBool usePrescribedBC, Vec *v, Mat Ae, Mat Ai, Mat Be, Mat Bi, Vec *uf, Vec *uef, Vec *bcc, Vec *bcf, Vec *vtmp); extern PetscErrorCode waitForSignal(PetscInt waitTime); #undef __FUNCT__ #define __FUNCT__ "main" int main(int argc,char **args) { PetscInt numTracers, n; Vec templateVec; Vec *v, *vtmp; /* TM's */ Mat Ae, Ai; PeriodicMat Aep, Aip; char mateFile[PETSC_MAX_PATH_LEN], matiFile[PETSC_MAX_PATH_LEN], rfsFile[PETSC_MAX_PATH_LEN]; PetscScalar *tdpMatrix; /* array for periodic matrix times */ PetscInt numMatrixPeriods; PetscBool periodicMatrix = PETSC_FALSE; PetscScalar matrixCyclePeriod, matrixCycleStep; /* Forcing */ Vec *uf, *uef; PeriodicVec up[MAXNUMTRACERS]; char *forcingFile[MAXNUMTRACERS]; PetscInt numForcingPeriods, numForcing; PetscScalar *tdpForcing; /* array for periodic forcing */ Vec **utdf; PetscScalar *tdfT; /* array for time dependent (nonperiodic) forcing */ PetscScalar forcingCyclePeriod, forcingCycleStep; PetscScalar tf0, tf1; /* Rescale forcing */ Vec Rfs; PeriodicVec Rfsp; /* BC's */ Vec *bcc, *bcf; PeriodicVec bcp[MAXNUMTRACERS]; char *bcFile[MAXNUMTRACERS]; PetscInt numBCPeriods, numBC; PetscScalar *tdpBC; /* array for periodic forcing */ Vec **bctd; PetscScalar *tdbcT; /* array for time dependent (nonperiodic) forcing */ PetscScalar bcCyclePeriod, bcCycleStep; PetscScalar tbc0, tbc1; PetscInt bcCutOffStep = -1; Mat Be, Bi; PeriodicMat Bep, Bip; char matbeFile[PETSC_MAX_PATH_LEN], matbiFile[PETSC_MAX_PATH_LEN]; Vec bcTemplateVec; PetscInt lBCSize, gBCSize; /* I/O */ char *iniFile[MAXNUMTRACERS]; char *outFile[MAXNUMTRACERS]; char pickupFile[PETSC_MAX_PATH_LEN]; char pickupoutFile[PETSC_MAX_PATH_LEN]; char outTimeFile[PETSC_MAX_PATH_LEN]; PetscBool appendOutput = PETSC_FALSE; PetscBool pickupFromFile = PETSC_FALSE; PetscBool doTimeAverage = PETSC_FALSE; PetscInt avgNumTimeSteps, avgStartTimeStep, avgCount; char *avgOutFile[MAXNUMTRACERS]; Vec *vavg; PetscViewer fdavgout[MAXNUMTRACERS]; FILE *fptime; PetscViewer fd, fdp, fdout[MAXNUMTRACERS], fdin[MAXNUMTRACERS]; /* run time options */ PetscBool useExternalForcing = PETSC_FALSE; PetscBool useForcingFromFile = PETSC_FALSE; PetscBool usePrescribedBC = PETSC_FALSE; PetscBool applyBC = PETSC_FALSE; PetscBool periodicForcing = PETSC_FALSE; PetscBool timeDependentForcing = PETSC_FALSE; PetscBool constantForcing = PETSC_FALSE; PetscBool periodicBC = PETSC_FALSE; PetscBool timeDependentBC = PETSC_FALSE; PetscBool constantBC = PETSC_FALSE; PetscBool doCalcBC = PETSC_FALSE; PetscBool rescaleForcing = PETSC_FALSE; PetscBool useMonitor = PETSC_FALSE; PetscMPIInt numProcessors, myId; PetscErrorCode ierr; PetscBool flg1,flg2; PetscScalar t1, t2, tc, tf; PetscInt iLoop, Iterc; PetscInt it; PetscInt itr, maxValsToRead; PetscInt itjac; PetscInt fp; char tmpFile[PETSC_MAX_PATH_LEN]; PetscScalar zero = 0.0, one = 1.0; PetscInt il; PetscInitialize(&argc,&args,(char *)0,help); ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&myId);CHKERRQ(ierr); ierr = MPI_Comm_size(PETSC_COMM_WORLD,&numProcessors);CHKERRQ(ierr); myId=myId+1; /* process ID (starting at 1) */ PetscPushErrorHandler(PetscAbortErrorHandler,NULL); /* force code to abort on error */ /* Some defaults */ time0=0.0; deltaTClock=1.0; Iter0=0; numTracers=1; /* Process options and load files */ /* Number of tracers */ ierr = PetscOptionsGetInt(PETSC_NULL,"-numtracers",&numTracers,&flg1);CHKERRQ(ierr); if (numTracers>MAXNUMTRACERS) { SETERRQ(PETSC_COMM_WORLD,1,"Number of tracers exceeds maximum allowable. Please increase the variable MAXNUMTRACERS and recompile"); } ierr = PetscPrintf(PETSC_COMM_WORLD,"Number of tracers to be integrated: %d\n", numTracers);CHKERRQ(ierr); /* Time step data */ ierr = PetscOptionsGetReal(PETSC_NULL,"-deltat_clock",&deltaTClock,&flg1);CHKERRQ(ierr); ierr = PetscOptionsGetReal(PETSC_NULL,"-t0",&time0,&flg1);CHKERRQ(ierr); ierr = PetscOptionsGetInt(PETSC_NULL,"-iter0",&Iter0,&flg2);CHKERRQ(ierr); if ((flg1) && (!flg2)) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate both or neither time0 and Iter0 with the -t0 and -iter0 flags"); if ((!flg1) && (flg2)) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate both or neither time0 and Iter0 with the -t0 and -iter0 flags"); ierr = PetscOptionsGetInt(PETSC_NULL,"-max_steps",&maxSteps,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate maximum number of steps with the -max_steps option"); ierr = PetscOptionsGetInt(PETSC_NULL,"-write_steps",&writeSteps,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate output step with the -write_steps option"); /*Data for time averaging */ ierr = PetscOptionsHasName(PETSC_NULL,"-time_avg",&doTimeAverage);CHKERRQ(ierr); if (doTimeAverage) { ierr = PetscOptionsGetInt(PETSC_NULL,"-avg_start_time_step",&avgStartTimeStep,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate (absolute) time step at which to start time averaging with the -avg_start_time_step flag"); ierr = PetscOptionsGetInt(PETSC_NULL,"-avg_time_steps",&avgNumTimeSteps,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate number of time averaging time steps with the -avg_time_step flag"); for (itr=0; itr1)) { ierr = MatSetSizes(Ae,lSize,lSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); ierr = MatSetSizes(Ai,lSize,lSize,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); } ierr = MatSetType(Ae,MATMPIAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(Ae);CHKERRQ(ierr); ierr = MatSetType(Ai,MATMPIAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(Ai);CHKERRQ(ierr); ierr = PetscOptionsHasName(PETSC_NULL,"-periodic_matrix",&periodicMatrix);CHKERRQ(ierr); if (periodicMatrix) { ierr=PetscPrintf(PETSC_COMM_WORLD,"Periodic matrices specified\n");CHKERRQ(ierr); ierr=PetscStrcat(mateFile,"_");CHKERRQ(ierr); ierr=PetscStrcat(matiFile,"_");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Ae basename is %s\n", mateFile);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Ai basename is %s\n", matiFile);CHKERRQ(ierr); /* read time data */ ierr = PetscOptionsGetReal(PETSC_NULL,"-matrix_cycle_period",&matrixCyclePeriod,&flg2);CHKERRQ(ierr); if (!flg2) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate matrix cycling time with the -matrix_cycle_period option"); ierr = PetscOptionsGetReal(PETSC_NULL,"-matrix_cycle_step",&matrixCycleStep,&flg2);CHKERRQ(ierr); if (!flg2) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate cycling step with the -matrix_cycle_step option"); numMatrixPeriods=matrixCyclePeriod/matrixCycleStep; /* array for holding extended time array */ PetscMalloc((numMatrixPeriods+2)*sizeof(PetscScalar), &tdpMatrix); ierr = PetscPrintf(PETSC_COMM_WORLD,"Periodic matrix specified at times:\n");CHKERRQ(ierr); for (it=0; it<=numMatrixPeriods+1; it++) { tdpMatrix[it]=(-matrixCycleStep/2.0) + it*matrixCycleStep; ierr = PetscPrintf(PETSC_COMM_WORLD,"tdpMatrix=%10.5f\n", tdpMatrix[it]);CHKERRQ(ierr); } /* Read here to set sparsity pattern */ strcpy(tmpFile,""); sprintf(tmpFile,"%s%02d",mateFile,0); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,tmpFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(Ae,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); strcpy(tmpFile,""); sprintf(tmpFile,"%s%02d",matiFile,0); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,tmpFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(Ai,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); Aep.firstTime = PETSC_TRUE; Aip.firstTime = PETSC_TRUE; } else { /* not periodic. read matrices here */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,mateFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading Ae from file %s\n", mateFile);CHKERRQ(ierr); ierr = MatLoad(Ae,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,matiFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading Ai from file %s\n", matiFile);CHKERRQ(ierr); ierr = MatLoad(Ai,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); } /* create template vector here if not using profiles */ if (!useProfiles) { ierr = MatGetSize(Ae,0,&n);CHKERRQ(ierr); ierr = VecCreate(PETSC_COMM_WORLD,&templateVec);CHKERRQ(ierr); ierr = VecSetSizes(templateVec,PETSC_DECIDE,n);CHKERRQ(ierr); ierr = VecSetFromOptions(templateVec);CHKERRQ(ierr); } ierr = PetscPrintf(PETSC_COMM_WORLD,"Matrix size is %d x %d\n", n,n);CHKERRQ(ierr); /* Compute global indices for local piece of vectors */ ierr = VecGetOwnershipRange(templateVec,&gLow,&gHigh);CHKERRQ(ierr); gHigh = gHigh - 1; /* Note: gHigh is one more than the last local element */ ierr = PetscMalloc(lSize*sizeof(PetscInt),&gIndices);CHKERRQ(ierr); for (il=0; il1)) { lBCSize = lNumProfiles; ierr = VecSetSizes(bcTemplateVec,lBCSize,PETSC_DECIDE);CHKERRQ(ierr); ierr = VecSetFromOptions(bcTemplateVec);CHKERRQ(ierr); } else { ierr = PetscOptionsGetInt(PETSC_NULL,"-bc_vec_size",&gBCSize,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate size of BC vector with the -bc_vec_size option"); ierr = VecSetSizes(bcTemplateVec,PETSC_DECIDE,gBCSize);CHKERRQ(ierr); ierr = VecSetFromOptions(bcTemplateVec);CHKERRQ(ierr); } ierr = VecDuplicateVecs(bcTemplateVec,numTracers,&bcc);CHKERRQ(ierr); ierr = VecDuplicateVecs(bcTemplateVec,numTracers,&bcf);CHKERRQ(ierr); ierr = iniCalcBC(time0,Iter0,time0+deltaTClock,Iter0+1,numTracers,v,bcc,bcf);CHKERRQ(ierr); } else { /* read from file */ for (itr=0; itr1)) { if (lBCSize != lNumProfiles) { SETERRQ(PETSC_COMM_WORLD,1,"Problem with partitioning of BC vectors! lNumProfiles must equal lBCSize"); } } applyBC = PETSC_TRUE; ierr = PetscOptionsGetInt(PETSC_NULL,"-bc_cutoff_step",&bcCutOffStep,&flg1);CHKERRQ(ierr); if (bcCutOffStep>0) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Prescribed BC will be turned off after time step %d\n",bcCutOffStep);CHKERRQ(ierr); } /* Matrices */ ierr = PetscOptionsGetString(PETSC_NULL,"-mbe",matbeFile,PETSC_MAX_PATH_LEN-1,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary boundary matrix file name with the -mbe option"); ierr = PetscOptionsGetString(PETSC_NULL,"-mbi",matbiFile,PETSC_MAX_PATH_LEN-1,&flg1);CHKERRQ(ierr); if (!flg1) SETERRQ(PETSC_COMM_WORLD,1,"Must indicate binary boundary matrix file name with the -mbi options"); ierr = MatCreate(PETSC_COMM_WORLD,&Be);CHKERRQ(ierr); ierr = MatCreate(PETSC_COMM_WORLD,&Bi);CHKERRQ(ierr); /* Set layout information */ if ((useProfiles) && (numProcessors>1)) { ierr = MatSetSizes(Be,lSize,lBCSize,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); ierr = MatSetSizes(Bi,lSize,lBCSize,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); } ierr = MatSetType(Be,MATMPIAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(Be);CHKERRQ(ierr); ierr = MatSetType(Bi,MATMPIAIJ);CHKERRQ(ierr); ierr = MatSetFromOptions(Bi);CHKERRQ(ierr); if (periodicMatrix) { ierr=PetscPrintf(PETSC_COMM_WORLD,"Periodic boundary matrices specified\n");CHKERRQ(ierr); ierr=PetscStrcat(matbeFile,"_");CHKERRQ(ierr); ierr=PetscStrcat(matbiFile,"_");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Be basename is %s\n", matbeFile);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Bi basename is %s\n", matbiFile);CHKERRQ(ierr); /* Read here to set sparsity pattern */ strcpy(tmpFile,""); sprintf(tmpFile,"%s%02d",matbeFile,0); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,tmpFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(Be,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); strcpy(tmpFile,""); sprintf(tmpFile,"%s%02d",matbiFile,0); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,tmpFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = MatLoad(Bi,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); Bep.firstTime = PETSC_TRUE; Bip.firstTime = PETSC_TRUE; } else { /* not periodic. read matrices here */ ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,matbeFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading Be from file %s\n", matbeFile);CHKERRQ(ierr); ierr = MatLoad(Be,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,matbiFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading Bi from file %s\n", matbiFile);CHKERRQ(ierr); ierr = MatLoad(Bi,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); } } else { /* no BC */ numBC=0; ierr = PetscPrintf(PETSC_COMM_WORLD,"No prescribed BC's specified\n");CHKERRQ(ierr); } ierr = PetscOptionsGetString(PETSC_NULL,"-rescale_forcing_file",rfsFile,PETSC_MAX_PATH_LEN-1,&rescaleForcing);CHKERRQ(ierr); if (rescaleForcing) { ierr = PetscPrintf(PETSC_COMM_WORLD,"Forcing will be rescaled\n");CHKERRQ(ierr); ierr = VecDuplicate(templateVec,&Rfs);CHKERRQ(ierr); if (periodicMatrix) { ierr=PetscStrcat(rfsFile,"_");CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Rescale forcing factor file basename is %s\n", rfsFile);CHKERRQ(ierr); Rfsp.firstTime = PETSC_TRUE; } else { ierr = PetscPrintf(PETSC_COMM_WORLD,"Reading rescale forcing factor from file %s\n", rfsFile);CHKERRQ(ierr); ierr = PetscViewerBinaryOpen(PETSC_COMM_WORLD,rfsFile,FILE_MODE_READ,&fd);CHKERRQ(ierr); ierr = VecLoad(Rfs,fd);CHKERRQ(ierr); ierr = PetscViewerDestroy(&fd);CHKERRQ(ierr); } } /* initialize monitor */ ierr = PetscOptionsHasName(PETSC_NULL,"-monitor",&useMonitor);CHKERRQ(ierr); if (useMonitor) { ierr = iniMonitor(time0,Iter0,numTracers,v);CHKERRQ(ierr); } /* initialize misfit */ ierr = PetscOptionsHasName(PETSC_NULL,"-calc_misfit",&doMisfit);CHKERRQ(ierr); if (doMisfit) { ierr = iniMisfit(time0,Iter0,numTracers,v);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Calculating misfit function.\n");CHKERRQ(ierr); } /* Open files for output and optionally write initial conditions */ #if !defined (FORSPINUP) && !defined (FORJACOBIAN) if (!appendOutput) { ierr = PetscFOpen(PETSC_COMM_WORLD,outTimeFile,"w",&fptime);CHKERRQ(ierr); ierr = PetscFPrintf(PETSC_COMM_WORLD,fptime,"%d %10.5f\n",Iter0,time0);CHKERRQ(ierr); ierr = PetscPrintf(PETSC_COMM_WORLD,"Writing output at time %10.5f, step %d\n", time0,Iter0);CHKERRQ(ierr); for (itr=0; itr iLoop+1 (convention) */ #if !defined (FORSPINUP) && !defined (FORJACOBIAN) tc=time0 + deltaTClock*(iLoop-1); /* current time (time at beginning of step) */ tf=time0 + deltaTClock*iLoop; /* future time (time at end of step) */ Iterc=Iter0+iLoop-1; #else tc=time0 + deltaTClock*(itjac-1); /* current time (time at beginning of step) */ tf=time0 + deltaTClock*itjac; /* future time (time at end of step) */ Iterc=Iter0+itjac-1; itjac++; #endif #ifdef FORJACOBIAN if (!doTimeAverage) { for (itr=0; itr0) && (iLoop==(bcCutOffStep+1))) { applyBC = PETSC_FALSE; doCalcBC = PETSC_FALSE; } else { if (periodicMatrix) { ierr = interpPeriodicMatrix(tc,&Be,matrixCyclePeriod,numMatrixPeriods, tdpMatrix,&Bep,matbeFile); ierr = interpPeriodicMatrix(tc,&Bi,matrixCyclePeriod,numMatrixPeriods, tdpMatrix,&Bip,matbiFile); } if (periodicBC) { for (itr=0; itr=avgStartTimeStep) { /* start time averaging (note: avgStartTimeStep is ABSOLUTE time step) */ if (avgCount<=avgNumTimeSteps) { /* still within same averaging block so accumulate */ for (itr=0; itr=avgStartTimeStep) { /* start time averaging (note: avgStartTimeStep is ABSOLUTE time step) */ if (avgCount<=avgNumTimeSteps) { /* still within same averaging block so accumulate */ /* ierr = PetscPrintf(PETSC_COMM_WORLD,"Accumulating for time average\n");CHKERRQ(ierr); */ for (itr=0; itr