xref: /libCEED/examples/solids/problems/neo-hookean.c (revision ae718e2f2476441c07fb6c037655a83f28d5f429)
1 #include <ceed.h>
2 #include <petsc.h>
3 #include "../problems/neo-hookean.h"
4 
5 // Build libCEED context object
6 PetscErrorCode PhysicsContext_NH(MPI_Comm comm, Ceed ceed, Units *units,
7                                  CeedQFunctionContext *ctx) {
8   PetscErrorCode ierr;
9   Physics_NH phys;
10 
11   PetscFunctionBegin;
12 
13   ierr = PetscMalloc1(1, units); CHKERRQ(ierr);
14   ierr = PetscMalloc1(1, &phys); CHKERRQ(ierr);
15   ierr = ProcessPhysics_NH(comm, phys, *units); CHKERRQ(ierr);
16   CeedQFunctionContextCreate(ceed, ctx);
17   CeedQFunctionContextSetData(*ctx, CEED_MEM_HOST, CEED_COPY_VALUES,
18                               sizeof(*phys), phys);
19   ierr = PetscFree(phys); CHKERRQ(ierr);
20 
21   PetscFunctionReturn(0);
22 }
23 
24 // Build libCEED smoother context object
25 PetscErrorCode PhysicsSmootherContext_NH(MPI_Comm comm, Ceed ceed,
26     CeedQFunctionContext ctx, CeedQFunctionContext *ctx_smoother) {
27   PetscErrorCode ierr;
28   PetscScalar nu_smoother = 0;
29   PetscBool nu_flag = PETSC_FALSE;
30   Physics_NH phys, phys_smoother;
31 
32   PetscFunctionBegin;
33 
34   ierr = PetscOptionsBegin(comm, NULL,
35                            "Neo-Hookean physical parameters for smoother", NULL);
36   CHKERRQ(ierr);
37 
38   ierr = PetscOptionsScalar("-nu_smoother", "Poisson's ratio for smoother",
39                             NULL, nu_smoother, &nu_smoother, &nu_flag);
40   CHKERRQ(ierr);
41 
42   ierr = PetscOptionsEnd(); CHKERRQ(ierr); // End of setting Physics
43 
44   if (nu_flag) {
45     // Copy context
46     CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &phys);
47     ierr = PetscMalloc1(1, &phys_smoother); CHKERRQ(ierr);
48     ierr = PetscMemcpy(phys_smoother, phys, sizeof(*phys)); CHKERRQ(ierr);
49     CeedQFunctionContextRestoreData(ctx, &phys);
50     // Create smoother context
51     CeedQFunctionContextCreate(ceed, ctx_smoother);
52     phys_smoother->nu = nu_smoother;
53     CeedQFunctionContextSetData(*ctx_smoother, CEED_MEM_HOST, CEED_COPY_VALUES,
54                                 sizeof(*phys_smoother), phys_smoother);
55     ierr = PetscFree(phys_smoother); CHKERRQ(ierr);
56   } else {
57     *ctx_smoother = NULL;
58   }
59 
60   PetscFunctionReturn(0);
61 }
62 
63 // Process physics options - Neo-Hookean
64 PetscErrorCode ProcessPhysics_NH(MPI_Comm comm, Physics_NH phys, Units units) {
65   PetscErrorCode ierr;
66   PetscBool nu_flag = PETSC_FALSE;
67   PetscBool Young_flag = PETSC_FALSE;
68   phys->nu = 0;
69   phys->E = 0;
70   units->meter     = 1;        // 1 meter in scaled length units
71   units->second    = 1;        // 1 second in scaled time units
72   units->kilogram  = 1;        // 1 kilogram in scaled mass units
73 
74   PetscFunctionBeginUser;
75 
76   ierr = PetscOptionsBegin(comm, NULL, "Neo-Hookean physical parameters", NULL);
77   CHKERRQ(ierr);
78 
79   ierr = PetscOptionsScalar("-nu", "Poisson's ratio", NULL, phys->nu, &phys->nu,
80                             &nu_flag); CHKERRQ(ierr);
81 
82   ierr = PetscOptionsScalar("-E", "Young's Modulus", NULL, phys->E, &phys->E,
83                             &Young_flag); CHKERRQ(ierr);
84 
85   ierr = PetscOptionsScalar("-units_meter", "1 meter in scaled length units",
86                             NULL, units->meter, &units->meter, NULL);
87   CHKERRQ(ierr);
88   units->meter = fabs(units->meter);
89 
90   ierr = PetscOptionsScalar("-units_second", "1 second in scaled time units",
91                             NULL, units->second, &units->second, NULL);
92   CHKERRQ(ierr);
93   units->second = fabs(units->second);
94 
95   ierr = PetscOptionsScalar("-units_kilogram", "1 kilogram in scaled mass units",
96                             NULL, units->kilogram, &units->kilogram, NULL);
97   CHKERRQ(ierr);
98   units->kilogram = fabs(units->kilogram);
99 
100   ierr = PetscOptionsEnd(); CHKERRQ(ierr); // End of setting Physics
101 
102   // Check for all required options to be set
103   if (!nu_flag) {
104     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "-nu option needed");
105   }
106   if (!Young_flag) {
107     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "-E option needed");
108   }
109 
110   // Define derived units
111   units->Pascal = units->kilogram / (units->meter * PetscSqr(units->second));
112 
113   // Scale E to Pa
114   phys->E *= units->Pascal;
115 
116   PetscFunctionReturn(0);
117 };