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