[cig-commits] commit:

Mercurial hg at geodynamics.org
Mon Nov 24 11:59:33 PST 2008


changeset:   153:b6372045cece
user:        LukeHodkinson
date:        Sun Aug 31 09:42:17 2008 +0000
files:       Utils/src/RegularRemesher.c
description:
Converting to an implicit Crank-Nicolson diffusion
scheme; the other explicit method was too unstable.


diff -r e03ad1906fc2 -r b6372045cece Utils/src/RegularRemesher.c
--- a/Utils/src/RegularRemesher.c	Sun Aug 31 07:16:11 2008 +0000
+++ b/Utils/src/RegularRemesher.c	Sun Aug 31 09:42:17 2008 +0000
@@ -31,6 +31,10 @@
 
 #include <stdlib.h>
 #include <string.h>
+#include <petsc.h>
+#include <petscvec.h>
+#include <petscmat.h>
+#include <petscksp.h>
 #include <StGermain/StGermain.h>
 #include <StgDomain/Geometry/Geometry.h>
 #include <StgDomain/Shape/Shape.h>
@@ -322,6 +326,81 @@ void _RegularRemesher_Remesh( void* _sel
       nodeVert[1] = innerVert[1] - (inner2Vert[1] - innerVert[1]);
    }
    else if( self->diffuseSurface ) {
+      Mat A;
+      Vec b, x;
+      KSP ksp;
+      int cols[3], nDofs, nodeIndex;
+      double one = 1.0, rhs, coef, *soln, vals[3];
+      double d, dt, sep;
+      int ii;
+
+      nDofs = vGrid->sizes[0];
+      VecCreateSeq( PETSC_COMM_SELF, nDofs, &x );
+      VecDuplicate( x, &b );
+      MatCreateSeqAIJ( PETSC_COMM_SELF, nDofs, nDofs, 3, PETSC_NULL, &A );
+
+      d = self->diffusionCoef;
+      dt = self->ctx->dt;
+      sep = Mesh_GetVertex( mesh, 1 )[0] - Mesh_GetVertex( mesh, 0 )[0];
+      coef = d * dt / (2.0 * (sep * sep));
+      vals[0] = coef; vals[1] = -2.0 * coef; vals[2] = coef;
+      inds[1] = vGrid->sizes[1] - 1;
+      for( ii = 0; ii < nDofs; ii++ ) {
+         if( ii == 0 ) {
+            cols[0] = ii; cols[1] = ii + 1; cols[2] = ii + 2;
+         }
+         else if( ii == nDofs - 1 ) {
+            cols[0] = ii - 2; cols[1] = ii - 1; cols[2] = ii;
+         }
+         else {
+            cols[0] = ii - 1; cols[1] = ii; cols[2] = ii + 1;
+         }
+         MatSetValues( A, 1, &ii, 3, cols, vals, ADD_VALUES );
+         MatSetValues( A, 1, &ii, 1, &ii, &one, ADD_VALUES );
+
+         inds[0] = ii;
+         nodeIndex = Grid_Project( vGrid, inds );
+         rhs = Mesh_GetVertex( mesh, nodeIndex )[1];
+         if( ii == 0 ) {
+            rhs -= coef * (Mesh_GetVertex( mesh, nodeIndex )[1] -
+                           2.0 * Mesh_GetVertex( mesh, nodeIndex + 1 )[1] + 
+                           Mesh_GetVertex( mesh, nodeIndex + 2 )[1]);
+         }
+         else if( ii == nDofs - 1 ) {
+            rhs -= coef * (Mesh_GetVertex( mesh, nodeIndex - 2 )[1] -
+                           2.0 * Mesh_GetVertex( mesh, nodeIndex - 1 )[1] + 
+                           Mesh_GetVertex( mesh, nodeIndex )[1]);
+         }
+         else {
+            rhs -= coef * (Mesh_GetVertex( mesh, nodeIndex - 1 )[1] -
+                           2.0 * Mesh_GetVertex( mesh, nodeIndex )[1] + 
+                           Mesh_GetVertex( mesh, nodeIndex + 1 )[1]);
+         }
+         VecSetValues( b, 1, &ii, &rhs, ADD_VALUES );
+      }
+
+      MatAssemblyBegin( A, MAT_FINAL_ASSEMBLY );
+      VecAssemblyBegin( b );
+      MatAssemblyEnd( A, MAT_FINAL_ASSEMBLY );
+      VecAssemblyEnd( b );
+
+      KSPCreate( PETSC_COMM_SELF, &ksp );
+      KSPSetOperators( ksp, A, A, DIFFERENT_NONZERO_PATTERN );
+      KSPSolve( ksp, b, x );
+
+      VecGetArray( x, &soln );
+      for( inds[0] = 0; inds[0] < vGrid->sizes[0]; inds[0]++ ) {
+         nodeIndex = Grid_Project( vGrid, inds );
+         mesh->verts[nodeIndex][1] = soln[inds[0]];
+      }
+      VecRestoreArray( x, &soln );
+
+      KSPDestroy( ksp );
+      MatDestroy( A );
+      VecDestroy( b );
+      VecDestroy( x );
+
+#if 0
       int nodeIndex, inds[2];
       double *newHeights, sep, d, dt;
       int ii;
@@ -364,6 +443,7 @@ void _RegularRemesher_Remesh( void* _sel
       }
 
       MemFree( newHeights );
+#endif
    }
 
    Class_Free( self, inds );



More information about the CIG-COMMITS mailing list