File: CapillaryStressRecorder.cpp

package info (click to toggle)
yade 2026.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 34,448 kB
  • sloc: cpp: 97,645; python: 52,173; sh: 677; makefile: 162
file content (138 lines) | stat: -rw-r--r-- 4,924 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*************************************************************************
*  Copyright (C) 2006 by luc scholtes                                    *
*  luc.scholtes@hmg.inpg.fr                                              *
*                                                                        *
*  This program is free software; it is licensed under the terms of the  *
*  GNU General Public License v2 or later. See file LICENSE for details. *
*************************************************************************/

#include "CapillaryStressRecorder.hpp"
#include <lib/high-precision/Constants.hpp>
#include <pkg/common/ElastMat.hpp>
#include <pkg/common/Sphere.hpp>
#include <pkg/dem/CapillaryPhys.hpp>
#include <pkg/dem/Law2_ScGeom_CapillaryPhys_Capillarity.hpp>
#include <pkg/dem/TriaxialCompressionEngine.hpp>

#include <core/Omega.hpp>
#include <core/Scene.hpp>

namespace yade { // Cannot have #include directive inside.

YADE_PLUGIN((CapillaryStressRecorder));
CREATE_LOGGER(CapillaryStressRecorder);

void CapillaryStressRecorder::action()
{
	shared_ptr<BodyContainer>& bodies = scene->bodies;

	// at the beginning of the file; write column titles
	if (out.tellp() == 0) { out << "iteration Scap11 Scap22 Scap33 Scap12 Scap13 Scap23 Uc Sr w" << endl; }
	if (!triaxialCompressionEngine) {
		vector<shared_ptr<Engine>>::iterator itFirst = scene->engines.begin();
		vector<shared_ptr<Engine>>::iterator itLast  = scene->engines.end();
		for (; itFirst != itLast; ++itFirst) {
			if ((*itFirst)->getClassName() == "TriaxialCompressionEngine") {
				LOG_DEBUG("stress controller engine found");
				triaxialCompressionEngine = YADE_PTR_CAST<TriaxialCompressionEngine>(*itFirst);
			}
		}
		if (!triaxialCompressionEngine) {
			LOG_ERROR("Stress controller engine not found, the recorder cannot be used.");
			return;
		}
	}

	Real f1_cap_x = 0, f1_cap_y = 0, f1_cap_z = 0, x1 = 0, y1 = 0, z1 = 0, x2 = 0, y2 = 0, z2 = 0;
	Real sig11_cap = 0, sig22_cap = 0, sig33_cap = 0, sig12_cap = 0, sig13_cap = 0, sig23_cap = 0, Vwater = 0, capillaryPressure = 0;
	int  j = 0;

	InteractionContainer::iterator ii    = scene->interactions->begin();
	InteractionContainer::iterator iiEnd = scene->interactions->end();
	for (; ii != iiEnd; ++ii) {
		if ((*ii)->isReal()) {
			const shared_ptr<Interaction>& interaction = *ii;

			CapillaryPhys* meniscusParameters = static_cast<CapillaryPhys*>(interaction->phys.get());

			if (meniscusParameters->meniscus) {
				j = j + 1;

				unsigned int id1 = interaction->getId1();
				unsigned int id2 = interaction->getId2();

				Vector3r fcap = meniscusParameters->fCap;

				f1_cap_x = fcap[0];
				f1_cap_y = fcap[1];
				f1_cap_z = fcap[2];

				Body* de1 = (*bodies)[id1].get();
				Body* de2 = (*bodies)[id2].get();

				x1 = de1->state->pos[0];
				y1 = de1->state->pos[1];
				z1 = de1->state->pos[2];
				x2 = de2->state->pos[0];
				y2 = de2->state->pos[1];
				z2 = de2->state->pos[2];

				/// capillary stresses from contact forces

				sig11_cap = sig11_cap + f1_cap_x * (x1 - x2);
				sig22_cap = sig22_cap + f1_cap_y * (y1 - y2);
				sig33_cap = sig33_cap + f1_cap_z * (z1 - z2);
				sig12_cap = sig12_cap + f1_cap_x * (y1 - y2);
				sig13_cap = sig13_cap + f1_cap_x * (z1 - z2);
				sig23_cap = sig23_cap + f1_cap_y * (z1 - z2);

				/// Liquid volume

				Vwater += meniscusParameters->vMeniscus;
				capillaryPressure = meniscusParameters->capillaryPressure;
			}
		}
	}

	/// Sample volume

	Real V = (triaxialCompressionEngine->height) * (triaxialCompressionEngine->width) * (triaxialCompressionEngine->depth);

	/// Solid volume
	Real Vs = 0, Rbody = 0, SR = 0;

	for (const auto& b : *bodies) {
		if (b->shape->getClassIndex() != Sphere::getClassIndexStatic()) continue;
		Sphere* sphere = static_cast<Sphere*>(b->shape.get());

		if (sphere) {
			Rbody = sphere->radius;
			SR += Rbody;
			Vs += 1.333 * Mathr::PI * (Rbody * Rbody * Rbody);
		}
	}

	Real Vv = V - Vs;
	Real Sr = 100 * Vwater / Vv;
	if (Sr > 100) Sr = 100;
	Real w = 100 * Vwater / V;
	if (w > (100 * Vv / V)) w = 100 * (Vv / V);

	/// homogeneized capillary stresses

	Real SIG_11_cap = 0, SIG_22_cap = 0, SIG_33_cap = 0, SIG_12_cap = 0, SIG_13_cap = 0, SIG_23_cap = 0;

	SIG_11_cap = sig11_cap / V;
	SIG_22_cap = sig22_cap / V;
	SIG_33_cap = sig33_cap / V;
	SIG_12_cap = sig12_cap / V;
	SIG_13_cap = sig13_cap / V;
	SIG_23_cap = sig23_cap / V;

	out << boost::lexical_cast<string>(scene->iter) << " " << boost::lexical_cast<string>(SIG_11_cap) << " " << boost::lexical_cast<string>(SIG_22_cap)
	    << " " << boost::lexical_cast<string>(SIG_33_cap) << " " << boost::lexical_cast<string>(SIG_12_cap) << " "
	    << boost::lexical_cast<string>(SIG_13_cap) << " " << boost::lexical_cast<string>(SIG_23_cap) << "   "
	    << boost::lexical_cast<string>(capillaryPressure) << " " << boost::lexical_cast<string>(Sr) << " " << boost::lexical_cast<string>(w) << " " << endl;
}

} // namespace yade